Re: [xsl] I need to make sure that all namespace declarations get output to a particular element, not the document element

Subject: Re: [xsl] I need to make sure that all namespace declarations get output to a particular element, not the document element
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Thu, 22 Mar 2007 15:08:07 +0100
David Carlisle wrote:
Not sure if the processor is allowed to, I think it is, to cleanup the
namespaces the way it likes and instead put the namespace decl. to
'test:other-ns-now' element.

That wouldn't be allowed, The XSLT1 output serialisation is allowed to move declarations up the tree, meaning a namespace is in scope earlier than one might expect, but it can never move a namespace declaration down the tree. If an element node in the result has a namespace node (even if that namespace is not used in any element or attribute) the namespace declaration must be serialised on the element or an ancestor.

How then, would you explain the behavior that in the following stylesheet, the namespace declaration created before it is used, but in the serialized output, it is placed on a descendant (namely the descendant that first uses the namespace)? If I read your words correctly, this should not be allowed to happen, but it does:


<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0"
xmlns:test="http://www.xyz.com";
exclude-result-prefixes="test">
<xsl:output indent="yes" />
<xsl:template match="/">
<root>
<def-ns-here />
<elem xmlns:test="http://www.xyz.com";>
<other-element-default-ns>
<test:other-ns-now>
<default-ns />
</test:other-ns-now>
</other-element-default-ns>
</elem>
</root>
</xsl:template>
</xsl:stylesheet>


will result in (Saxon 6.5.5)

<root>
  <def-ns-here/>
  <elem>
     <other-element-default-ns>
        <test:other-ns-now xmlns:test="http://www.xyz.com";>
           <default-ns/>
        </test:other-ns-now>
     </other-element-default-ns>
  </elem>
</root>

which means, imo, that the declaration for the 'http://www.xyz.com' namespace, which is put on the RLE 'elem' is moved to an descendant, namely the 'test:other-ns-now' element.

This does not change the output in any way, except for the location of the namespace declaration. If I remove the exclude-result-prefixed, the namespace is put on 'root', if I remove the namespace declaration the 'http://www.xyz.com' namespace from the xsl:stylesheet, the namespace declaration is left in the serialized output tree where I originally put in the stylesheet: the element 'test:other-ns-now'.

I personally never worry about namespaces. They always work correctly. And whether there's cleanup or not, I never encountered a situation where a namespace is declared after it is used (which would make the XML invalid to what is requested in your stylesheet declarations).

Cheers,
-- Abel Braaksma
  http://www.nuntia.nl

Current Thread