One of the difficulties in versioning languages is specifying the exact version(s) of the components. XML has compounded this problem by making the full name of a component contain the namespace, which is a single value that typically reflects the version of the language. Imagine we have our favorite language, a name language. V1 of the language specifies that Names consist of Given followed by Family: Name V1 = Given, Family. V2 adds an optional Middle at the end: Name V2 = Given, Family, Middle?
If my software "knows" about both V1 and V2 languages and I create a Name that only has Given and Family, should I call it Name V1 or Name V2? The problem is that a V1 Consumer might have problems with V2 instances if I've changed the namespace name. This is the primary reason why I advocate that XML languages specify that there are no namespace changes if the change is compatible.
The assignment of versions is especially difficult in forwards compatibility cases, where the consumer doesn't know anything about the version it may receive. I wrote about this in Forwards compatibility with version #s requires version # mapping
How does a consumer that knows about V1.0 know anything about things identified V1.01, V1.1, V2.0, or any other Version identifier?
There are a few potential approaches:
- If it's compatible, don't change the name. So there wouldn't be a V1.01 or V1.1 in the identifier.
- Specify all the versions that the name is compatible with. The Name would specify V1.0, V1.01, and V1.1
- Specify a range of versions that the name is compatible with, perhaps even listing ranges. The Name would specify V1.*.
Given the use of namespaces, could we flexibly define namespaces for the Name components to say that the Name components are in multiple namespaces? Let us assume that the namespace changes for each version, ie http://example.org/ns/name/1.0; http://example.org/ns/name/1.01; http://example.org/ns/name/1.1;
Unfortunately, we can't list each of the namespaces in the namespace declaration, such as:
<namens:PersonName xmlns:namens="http://example.org/ns/name/1.0 http://example.org/ns/name/1.01 http://example.org/ns/name/1.1">
This model could have allowed the consumer to pick which namespace it wanted to bind the Names to.
Another alternative would be to have multiple xmlns declaration, such as:
As an aside, both of these examples illustrate the results of not providing extensibility. If XML had allowed multiple URIs in the xmlns declaration and the namespaces 1.0 specification said that only the first was used and the rest ignored, then we could have revised the namespaces specification to support this kind of functionality.
What could work is a custom attribute that provided the alternative namespaces. The application would have to have hooks to choose the desired namespace and then apply it.
So the app could decide that it understood version 1.1 and override the xmlns:namens attribute with the 1.1 value.
This also solves the XPath problem: which is how to have namespace changes that don’t break XPaths that use particular namespace names. In this case, the application’s XPath expressions use the version 1.1 namespace.