Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

xsl:key issues, can anyone explain ?

Status
Not open for further replies.

simonchristieis

Programmer
Jan 10, 2002
1,144
GB

when I use a key:

Code:
<root>
<node>
<name>foo</name>
</node>
<node>
<name>bar</name>
</node>
</root>

Code:
<xsl:key name="bob" match="node[contains(name,'foo')]" use="name"/>

<xsl:apply-templates select="root/node[count(.|key('bob',name)[1])=1]" mode="test"/>

<xsl:template match="node" mode="test">
<xsl:value-of select="."/>
</xsl:template>

This prints out both foo and bar, can anyone explain why ?
 
[1] >This prints out both foo and bar, can anyone explain why ?
This is kind of verbose to do.
[1.1] What is the key doing here?
><xsl:key name="bob" match="node[contains(name,'foo')]" use="name"/>
Here is the content of the key so referred. It is storing/returning something like this for this document when it gets a match of the good "node".
[tt] <name>foo</name>[/tt]
because its use attribute is name. (If more matches, more name node will be contained in the key.)
[1.2] What's wrong in the use within the template?
>xsl:apply-templates select="root/node[count(.|key('bob',name)[1])=1]" mode="test"/>
[1.2.1] First you pass a name to its 2nd parameter.
>key('bob',name)
This will _never_ have a chance to return anything at all, because the key is designed to match "node" not "name". Hence, the key returns empty _all the time_.
[1.2.2] The position [1] is thereby unable to ever leading to anything.
[1.2.3]
>count(.|key('bob',name)[1])=1
Since you count the context node (.) or key return, it is always count(...)=1 met, disregard whether it is bar or foo.
[1.2.4] Hence the mode="test" template is executed all the time.

[2] To salvage the script, there are many ways depending on how the xml document has been stripped down. This is one way.
[tt]
<xsl:key name="bob" select="node[contains(name,'foo')]" use="." />

<xsl:apply-templates select="root/node[count(key('bob',.) != 0]" mode="test" />
[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top