xsl-list
[Top] [All Lists]

[xsl] Priority issue with select="node()"

2016-07-21 09:44:24
Hi,

I have an xml file where I want to filter out all instances of a particular 
element *except* those with specific attributes. I have got some XSLT that does 
this.

Here is an example of the XML that needs filtered:

<resource>
    <method href="ref1"/>
    <method href="ref2"/>
    <method href="ref3"/>
 </resource>

And here is the XSLT that I am using:

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                >

    <xsl:template match="node()">
       <xsl:call-template name="identity"/>
   </xsl:template>

    <xsl:template
            match="
                  /
                 | @*
                 | method[@href = 'ref1']
                 ">
        <xsl:call-template name="identity"/>
    </xsl:template>

    <xsl:template match="method"/>

    <xsl:template name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@* | node() " />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

When I use Saxon on the command line to transform the XML, I get this output:

<?xml version="1.0" encoding="UTF-8"?><resource>
    <method href="ref1"/>


 </resource>

Which is exactly what I want. 

The first two templates are identical in terms of content, but if I try to 
combine them into one template by combining their match attributes like this:

match="
                  /
                 | @*
                 | method[@href = 'ref1']
                 | node()
                 "

I get the following output

<?xml version="1.0" encoding="UTF-8"?><resource>
    <method href="ref1"/>
    <method href="ref2"/>
    <method href="ref3"/>
 </resource> 

It looks like a priority issue – for some reason the node() match is higher 
priority than the <xsl:template match="method"/> when it is included in the 
other template, but not when it is in its own template.

I can’t see why this is happening. Section 6.4 of the spec 
<https://www.w3.org/TR/xslt20/#conflict> says “If the pattern contains multiple 
alternatives separated by | , then the template rule is treated equivalently to 
a set of template rules, one for each alternative.” This implies to me that the 
priority shouldn’t change just because node() is now included alongside the 
other alternatives in a single match attribute.




<Prev in Thread] Current Thread [Next in Thread>