RE: [xsl] Getting the root namespace from the input document

Subject: RE: [xsl] Getting the root namespace from the input document
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 6 Feb 2007 13:55:23 -0000
The XSLT 2.0 spec is pretty clear, I think: see

http://www.w3.org/TR/xslt20/#constructing-complex-content

rules 7 and 8 in particular.

I think this should give [ERR XTDE0430]: when processing the my:other
element, the xsl:copy puts the namespace node (my, other-uri) in the result,
and the xsl:copy-of then adds the namespace node (my, namespace-double.xsl),
which should be detected as a conflict.

I think the rules in XSLT 1.0 are the same. The effect of xsl:copy and
xsl:copy-of when applied to namespace nodes is defined by erratum E25, which
says "It is an error to add a namespace node to an element if the element
already has a namespace node with the same name, unless both namespace nodes
have the same string-value, in which case the duplicate is ignored."

In both cases (and this is the tricky bit internally) namespace nodes
generated explicitly (e.g. by xsl:copy-of select="namespace::*") take
precedence over namespaces generated as a result of namespace fixup, which
means they can force you to choose a different prefix for the containing
element node.

So Saxon 6 is getting this right, and Saxon 8 is getting it wrong. (When a
namespace node is generated, there's a flag that goes with it to say whether
a confict should be treated as an error. This flag isn't being set when it's
a copy instruction that's responsible for creating the namespace node. I'll
fix this: though it's the kind of fix that needs to be regression tested
pretty thoroughly because the rules for namespaces have so many corner
cases, and because the logic within the implementation is a rather distant
cousin of the logic in the spec.)

Note that when copying or adding a namespace node explicitly to the result
tree, prefixes are never changed. The only time the processor has the
ability to decide a prefix is when namespace nodes are generated by the
namespace fixup process (that is, when you create an element or attribute
node with a namespaced name and the processor has to invent a namespace node
to bind the prefix to the uri): and in 2.0, the processor is obliged to
respect the requested prefixes unless there is a conflict.

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



> -----Original Message-----
> From: Florent Georges [mailto:darkman_spam@xxxxxxxx]
> Sent: 06 February 2007 11:33
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] Getting the root namespace from the input document
>
> Michael Kay wrote:
>
>   Hi
>
> > There's also sometimes a theoretical risk that prefixes will be
> > changed because XSLT 1.0 permits it
>
>   Yes, it is what I thought about.
>
> > but mainstream processors all do the decent thing in
> straightforward
> > cases.
>
>   And that is why I use it.  But I'm not very comfortable
> with the use of this "observable behaviour" without knowing
> exactly how this happens (prefixes will be changed in
> particular cases or not?).
>
>   In XSLT 2.0, the transformation fails if you try to create
> a namespace node whose the prefix is already bound to another
> namespace URI.  I like that.  In XSLT 1.0, the transformation
> succeed, your result is not correct and the error will
> propagate further in the chain.
>
>   Mmh, before to post, I just wrote a little test.  Input:
>
>     <my:same xmlns:my="namespace-double.xsl">
>       <my:other xmlns:my="other-uri"/>
>     </my:same>
>
> Stylesheet:
>
>     <xsl:stylesheet
>         xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>         xmlns:exsl="http://exslt.org/common";
>         xmlns:my="namespace-double.xsl"
>         exclude-result-prefixes="exsl"
>         version="1.0">
>
>       <xsl:output indent="yes" omit-xml-declaration="yes"/>
>
>       <xsl:template match="*">
>         <xsl:variable name="dummy-ns">
>           <my:e/>
>         </xsl:variable>
>         <xsl:copy>
>           <xsl:copy-of select="
>              exsl:node-set($dummy-ns)/*/namespace::*"/>
>           <xsl:attribute name="added">my:value</xsl:attribute>
>           <xsl:apply-templates select="@*|node()"/>
>         </xsl:copy>
>       </xsl:template>
>
>       <xsl:template match="@*|node()" priority="-1">
>         <xsl:copy>
>           <xsl:apply-templates select="@*|node()"/>
>         </xsl:copy>
>       </xsl:template>
>
>     </xsl:stylesheet>
>
>   I tested it with Saxon 6, Saxon 8, Xalan and xsltproc.
> Actually, Saxon 6 was the only one to generate an error:
>
>     Error at xsl:copy-of on line 16 of namespace-double.xsl:
>       Cannot create two namespace nodes with the same name
>     Transformation failed: Run-time errors were reported
>
>   I thought in this case an XSLT 1.0 processor will change
> one of the prefixes and not generate an error, but I didn't
> find the right verses in the XSLT 1.0 REC.  Does any one know
> those verses?
>
>   Furthemore, I thought Saxon 8 didn't throw an error because
> it was in compatibility mode, but the transformation succeed
> even with an XSLT 2.0 stylesheet.  It fails if we use
> xsl:namespace to create the node, but not if we use
> xsl:copy-of to copy it.  Again, I didn't find in the XSLT 2.0
> REC the difference between xsl:namespace and xsl:copy-of
> regarding the duplicate namespace node names.  Any pointer?
>
>   Regards,
>
> --drkm
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> ______________________________________________________________
> _____________
> Dicouvrez une nouvelle fagon d'obtenir des riponses ` toutes
> vos questions !
> Profitez des connaissances, des opinions et des expiriences
> des internautes sur Yahoo! Questions/Riponses
> http://fr.answers.yahoo.com

Current Thread