Name of iteration variable in xsl:for-each on xsl:key in XSLT 1.0
Question
I have XSLT 1.0 code like this:
<xsl:key name="enemyItems"
match="metadata[attributes/metadata_key/@value = 'enemylist']"
use="attributes/metadata_refkey/@value"/>
<xsl:template match="item">
<xsl:variable name="enemyList"
select="key('enemyItems', @key)/attributes/@value"/>
<xsl:if test="string-length($enemyList) > 0">
<xsl:value-of select="@name"/>
</xsl:if>
</xsl:template>
As I understand it, a key can store more than one value for a particular element. I believe the code above is only getting the first value when referring to key('enemyItems', @key)
.
So, I want to wrap that code in an xsl:for-each, like this
<xsl:template match="item">
<xsl:for-each select="key('enemyItems', @key)">
<xsl:variable name="enemyList"
select="???/attributes/@value"/>
<xsl:if test="string-length($enemyList) > 0">
<xsl:value-of select="@name"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
My question is: What goes in the ??? part? (That is, what is the name of the iteration variable or thing?)
Solution
Inside an xsl:for-each tag, the context on each iteration is the node being examined. Thus the ???
in your question should be replaced with .
OTHER TIPS
As I understand it, a key can store more than one value for a particular element
No. A key may map a value with more than one node.
So, here:
<xsl:variable name="enemyList"
select="key('enemyItems', @key)/attributes/@value"/>
<xsl:if test="string-length($enemyList) > 0">
<xsl:value-of select="@name"/>
</xsl:if>
You're saying: let be $enemyList all the value
attributes from attributes
child elements from every node wich has a 'enemyItems' key with value equal to context node's key
attribute, and if the string lenght of the string value from the first node in $enemyList node set is greater than 0, then output the value of context node's name
attribute.
EDIT: In your second XSLT fragment:
<xsl:template match="item">
<xsl:for-each select="key('enemyItems', @key)">
<xsl:variable name="enemyList"
select="???/attributes/@value"/>
<xsl:if test="string-length($enemyList) > 0">
<xsl:value-of select="@name"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
Now, inside for-each
, the context node is every node wich map with the key. So, you could define $enemyList
like:
<xsl:variable name="enemyList" select="attributes/@value"/>
This could also return several nodes if there ara more than one attributes
child having a value
attribute. But now, this:
<xsl:value-of select="@name"/>
It's de name
attribute of the context node... (the one wich map with the key)