Description
Consider the following element:
<p:root xmlns='urn:ns1' xmlns='urn:ns2'/>
When OMElement#resolveQName is used to resolve an unprefixed QName literal relative to this element, then the returned QName object has:
namespaceURI = urn:ns1
prefix = p
The reason is that ElementHelper#resolveQName contains code that will pick up the namespace of the parent element if the QName literal is unprefixed. This applies to the LLOM and DOOM implementations.
However, none of the XML specs describe a QName resolution algorithm that works like that. There are only two valid options to resolve a QName:
A. Resolve it in the same way as element names, i.e. an unprefixed QName literal will be interpreted based on the default namespace in scope. This is what the XML schema spec requires [1] for the QName type:
[quote]
1 If its - normalized value- is prefixed, then all of the following must be true:
1.1 There must be a namespace in the [in-scope namespaces] whose [prefix] matches the prefix.
1.2 its - namespace name- is the [namespace name] of that namespace.
1.3 Its - local name- is the portion of its - normalized value- after the colon (':').
2 otherwise (its - normalized value- is unprefixed) all of the following must be true:
2.1 its - local name- is its - normalized value- .
2.2 The appropriate case among the following must be true:
2.2.1 If there is a namespace in the [in-scope namespaces] whose [prefix] has no value, then its - namespace name- is the [namespace name] of that namespace.
2.2.2 otherwise its - namespace name- is - absent- .
[/quote]
B. Resolve it in the same way as attribute names, i.e. an unprefixed QName literal will have no namespace. This is what the XSL spec requires [2] for QNames appearing in XPath expressions:
"the set of namespace declarations are those in scope on the element which has the attribute in which the expression occurs; this includes the implicit declaration of the prefix xml required by the the XML Namespaces Recommendation [XML Names]; the default namespace (as declared by xmlns) is not part of this set"
Since OMElement#resolveQName is in general used to interpret literals of the QName schema type, it should implement algorithm A. For the specific case of XPath expressions, AXIOMXPath#addNamespaces(OMElement) already implements algorithm B.
Unit tests are already available, but they are currently excluded from the LLOM and DOOM test suites:
TestResolveQNameWithDefaultNamespace
TestResolveQNameWithoutNamespace
It should not be difficult to fix the resolveQName implementation. The only uncertainty is whether downstream projects such as Axis2 depend on the current behavior.
[1] http://www.w3.org/TR/xmlschema-1/#src-qname
[2] http://www.w3.org/TR/xslt#section-Expressions