[xquery-talk] Namespace question wrt. XQTS and XQuery/XSLT2Serialization spec

Michael Kay mhk at mhk.me.uk
Sun Nov 13 17:16:58 PST 2005


 
> I'm wondering what the correct output of the XML Output 
> Method of the  
> W3C XQuery/XSLT2 Serialization Spec is wrt. inclusion of namespaces  
> declared on ancestors in the context of subtrees. There are at least  
> two interpretations:
> 
> Example:
>          doc :=
>          <SOAP:a xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:foo="http://example.com">
>              <b>
>                  <SOAP:c/>
>              </b>
>          </SOAP:a>

In the above situation the SOAP namespace is an in-scope namespace for all
three elements, a, b, and c. The data model doesn't distinguish between the
above input and

doc :=
>          <SOAP:a xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:foo="http://example.com">
>              <b xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:foo="http://example.com">
>                  <SOAP:c
xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:foo="http://example.com"/>
>              </b>
>          </SOAP:a>

So the question is the same as asking whether the serializer retains all the
namespaces of an element, or only those that are actually used. The answer
is that it can't know which namespaces are actually used (because of the
possibility of namespace-sensitive content) so it retains them all.
> 
> result sequence := /*:*/b
> 
> 1) Output method 1 adds all namespaces-in-scope to the subforest's  
> root, generating the following output:
> 
>          <b xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"  
> xmlns:foo="http://example.com">
>              <SOAP:c/>
>          </b>

This is the correct output. It has to be this way because b might contain
namespace-sensitive content (e.g. attributes) that depends on the SOAP
namespace being in scope.

> 
> 2) Output method 2 omits superflous namespaces declarations, 
> treating  
> the subforest's root as if it had no ancestors:
> 
>          <b>
>              <SOAP:c xmlns:SOAP="http://schemas.xmlsoap.org/soap/ 
> envelope/"/>
>          </b>
>

This output is incorrect.
 
> I noticed that W3C XQTS requires method 2) at times due to Canonical  
> XML comparison, e.g. for SeqUnion/fn-union-node-args-015.xq et al.  

This shows up a deficiency in the test driver I have been using for testing
Saxon. I'm comparing results using the deep-equals() method, which doesn't
require two elements to have the same in-scope namespaces in order to be
deep equal. A more rigorous comparator would have spotted this error in the
published test results.

Saxon's actual results for this query are:

<?xml version="1.0" encoding="UTF-8"?>
<atomic:integer xmlns:atomic="http://www.w3.org/XQueryTest" 
                xmlns:foo="http://www.example.com/foo"
 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">12678967543233</atomic
:integer>

There's a possible question about what happens if you specify

declare copy-namespaces no-preserve, no-inherit;

This query is not actually creating or copying any nodes, so the prolog
declaration wouldn't appear to make any difference. Serialization does copy
the element (Serialization section 2 rule 1) but I don't think a copy
operation performed by the serializer is subject to the copy-namespaces
declaration (which can vary, after all, from one query module to another).
If you do this, however:

declare copy-namespaces no-preserve, no-inherit;
document {
  ($input-context/atomic:root/atomic:integer) union
($input-context/atomic:root/atomic:integer)
}

then the element node is copied, and the redundant namespaces are therefore
dropped.

If you're using XML 1.1 you can specify xmlns:foo="", and the foo namespace
will then not be in scope for this element, and no namespace declaration
will therefore be output by the serializer. 

Michael Kay
http://www.saxonica.com/




More information about the talk mailing list