Reputation: 3024
There is something about XSL matching rules I cannot get.
I've this input:
<root>
<metadata>
</metadata>
<elements>
<a-elems>
<a>A1</a>
<a>A2</a>
</a-elems>
<b-elems>
<b>B1</b>
<b>B2</b>
</b-elems>
</elements>
</root>
This XSL works as I want, a list of <a>
values is reported:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template match = "/">
_____ Elements _____
<xsl:apply-templates select = "root/elements/*/*" />
</xsl:template>
<xsl:template match = "a-elems/a">
__ A ELEM: <xsl:value-of select = "."></xsl:value-of> __
</xsl:template>
<xsl:template match="*">
<xsl:message>Excluding <xsl:value-of select = "name(.)" /></xsl:message>
</xsl:template>
</xsl:stylesheet>
However, I think this root template, where I state the level I want to start from, would be cleaner:
<xsl:template match = "/root/elements">
_____ Elements _____
<xsl:apply-templates select = "*/*" />
</xsl:template>
But it doesn't work, I get the 'Excluding root' message and I understand the template never matches. I don't get why, I've also tried select = "*" and adding priority attributes.
Upvotes: 0
Views: 26
Reputation: 70648
XSLT will start off by looking for a template that matches /
(the document node). By changing the template that matches /
to /root/elements
will result in XSLT using it's built-in template rule for matching /
instead. This built-in template is effectively this:
<xsl:template match = "/">
<xsl:apply-templates />
</xsl:template>
The xsl:apply-templates
will select the child root
node. This will then be matched by the template matching *
and so you get your message, and no more process is done.
The easiest solution would be to go back to what you had.
EDIT: In answer to your comment, you don't always have to redefine the /
. Another slight variation of your original solution would be to do this...
<xsl:template match = "root">
_____ Elements _____
<xsl:apply-templates select = "elements/*/*" />
</xsl:template>
Upvotes: 1