Reputation: 41
This is an example of my xml code:
<db>
<group>
<name>Team1</name>
<set num="1">AAA</set>
<set num="2">BBB</set>
<set num="3">CCC</set>
</group>
<group>
<name>Team2</name>
<set num="1">DDD</set>
<set num="2">AAA</set>
<set num="3">FFF</set>
<set num="4">EEE</set>
</group>
<group>
<name>Team3</name>
<set num="1">AAA</set>
<set num="2">GGG</set>
<set num="3">FFF</set>
</group>
<group>
<name>Team4</name>
<set num="1">BBB</set>
<set num="2">EEE</set>
<set num="3">AAA</set>
</group>
</db>
How would I use xslt to display the name and num of all instances where AAA has a num less than 3, so my output would look something like this:
<result value="AAA">
<name num="1">Team1</name>
<name num="2">Team2</name>
<name num="1">Team3</name>
</result>
The code I have been trying to use is as follows:
...
<xsl:template match="/db">
<result value="AAA">
<xsl:for-each select="group[set/@num < '3' and set='AAA']">
<name num="{@num}">
<xsl:value-of select="name" />
</name>
</xsl:for-each>
</result>
</xsl:template>
But this give me all groups that contain "AAA" regardless of num, and the num always displays as "" no matter what.
Any help would be appreciated as I am new to XSLT. Thanks!
Upvotes: 1
Views: 10324
Reputation: 11953
This should do it:
<xsl:template match="/db">
<result value="AAA">
<xsl:for-each select="group[set[@num < 3 and string(.)='AAA']]">
<name num="{set[@num < 3 and string(.)='AAA']/@num}">
<xsl:value-of select="name" />
</name>
</xsl:for-each>
</result>
</xsl:template>
the problem is that set/@num < '3' and set='AAA'
tests separately @num
and set
, whereas what is needed is a set
element that matches both conditions at the same time - that is done with the nested restriction [set[@num < 3 and string(.)='AAA']]
= all groups that have a set
sub-element that has @num
less than 3 and contains AAA
.
The same test is repeated to get the value of @num
from the correct set
sub-element.
An alternative to avoid repeating the test:
<xsl:template match="/db">
<result value="AAA">
<xsl:for-each select="group">
<xsl:variable name="theSet" select="set[@num < 3 and string(.)='AAA']"/>
<xsl:if test="$theSet">
<name num="{$theSet/@num}">
<xsl:value-of select="name" />
</name>
</xsl:if>
</xsl:for-each>
</result>
</xsl:template>
Upvotes: 1