xsl-list
[Top] [All Lists]

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

2007-02-06 06:55:43
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(_at_)yahoo(_dot_)fr] 
Sent: 06 February 2007 11:33
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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




















      

      
              
______________________________________________________________
_____________
Découvrez une nouvelle façon d'obtenir des réponses à toutes 
vos questions ! 
Profitez des connaissances, des opinions et des expériences 
des internautes sur Yahoo! Questions/Réponses 
http://fr.answers.yahoo.com

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--