Reputation: 4054
Suppose I have the following XML:
<root>
<a>1</a>
<b>2</b>
<a>3</a>
<c>4</c>
<a>5</a>
<a>6</a>
<b>7</b>
<a>8</a>
<c>9</c>
</root>
Consider the following XSL:
<xsl:template match="root">
<xsl:apply-templates select="a | b | c"/> <!-- matches node 'b' with a non-mode template instead of the one with mode="test" -->
</xsl:template>
<xsl:template match="a">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="b">
<xsl:text> ignore </xsl:text>
</xsl:template>
<xsl:template match="b" mode="test">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="c">
<xsl:value-of select="."/>
</xsl:template>
I am trying to write a XSL template call which will match all the nodes inside the root node with its corresponding template but the node b
should be matched with a template with mode="test"
. The order of the node handling should not be disturbed.
The desired output is:
1
2
3
4
5
6
7
8
9
Upvotes: 0
Views: 196
Reputation: 163458
I would define a new mode, and then redirect it as appropriate:
<xsl:template match="root">
<xsl:apply-templates select="a | b | c" mode="new"/>
</xsl:template>
<xsl:template match="a|c" mode="new">
<xsl:apply-templates select="."/>
</xsl:template>
<xsl:template match="b" mode="new">
<xsl:apply-templates select="." mode="test"/>
</xsl:template>
Another solution is to define template rules that apply in more than one mode, so the "unnamed mode" templates for a and c would also apply to mode "new", while the mode="test" template for b would also apply to mode "new". IIRC this requires XSLT 2.0 (you don't say which version you are using - please do so in future).
Upvotes: 1
Reputation: 7173
I do not know if this will be applicable to you. Instead of
<xsl:template match="root">
<xsl:apply-templates select="a | b | c"/>
</xsl:template>
do
<xsl:template match="root">
<xsl:for-each select="*">
<xsl:choose>
<xsl:when test="name()='a'">
<xsl:apply-templates select="."/>
</xsl:when>
<xsl:when test="name()='b'">
<xsl:apply-templates select="." mode="test"/>
</xsl:when>
<xsl:when test="name()='c'">
<xsl:apply-templates select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
Upvotes: 2