问题
I had posted another question with this as one aspect of it. I was told to clarify the question, but that question was already pretty long and complicated, so I created a new one.
I want to know if there is standard way of referencing the current node's attribute in an XPath expression testing for another one.
For an example, consider the following XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="potato/stem[eye]">
In session <xsl:value-of select="@sessionID"/>, the potato had <xsl:value-of select="/potato/stem[@sessionID=@sessionID][scc]/scc/@leafnumber"/> s.c.c. leaves.
</xsl:for-each>
</xsl:template>
(XML source at bottom of this question.) (Note that the for-each references nodes of type stem[eye] but the second value requested references nodes of type stem[scc], which are on a different branch of the source XML tree.)
Now, obviously, the "@sessionID=@sessoinID" part of that is mostly meaningless because XPath perceives this as "The value of the sessionID attribute of the node should equal ... the value of the sessionID attribute of the node."
But what I want to say is "Test to make sure the value of the seesionID attribute of that node (the one in the XPath expression) is the same as the sessionID of the node of whatever /stem[eye] node I'm in right now."
I can't do this with a variable, because you are not allowed to declare a variable within a for-each clause.
For reference, this is the XML source. Its structure is not what one would like, but it is what I have to work with.
<?xml version="1.0" encoding="utf-8"?>
<potato>
<stem sessionID="1">
<eye number = "25"/>
</stem>
<stem sessionID="3">
<eye number = "33"/>
</stem>
<stem sessionID="1">
<scc leafnumber = "234" />
</stem>
<stem sessionID="2">
<scc leafnumber = "433"/>
</stem>
<stem sessionID="3">
<scc leafnumber = "463"/>
</stem>
<stem sessionID="1">
<agd leafnumber = "154"/>
</stem>
<stem sessionID="2">
<agd leafnumber = "233"/>
</stem>
<stem sessionID="3">
<agd leafnumber = "113"/>
</stem>
</potato>
The output I'm looking for is:
In session 1, the potato had 234 s.c.c. leaves.
In session 3, the potato had 463 s.c.c. leaves.
(Of course, this is all just sandbox example. I realize there are probably easy ways to accomplish the above output in a completely different manner, but I hope this example gets across my question, which is how to use values associated with the current node (say, in a for-each) in a predicate for an XPath searching out a different one.)
回答1:
In XSLT 1.0 you can use the standard function current()
which refers to the node that is matched by the current template or the inner-most xsl:for-each
:
/potato/stem[@sessionID=current()/@sessionID][scc]/scc/@leafnumber
or by defining a key (at a global level):
<xsl:key name="kPotById" match="stem[scc]" use="@sessionID"/>
and referencing this key:
key('kPotById', @sessionID)/scc/@leafnumber
In XSLT 2.0 / XPath 2.0 you have additional ways to express this (range variables):
for $thisSessionID in @sessionId
return
/potato/stem[@sessionID=$thisSessionID][scc]/scc/@leafnumber
回答2:
Use e.g. current()/@sessionID
to access the sessionID
attribute of the currently processed node (e.g. the one processed by the for-each in your sample or by an apply-templates with push processing).
来源:https://stackoverflow.com/questions/7926680/xslt2-how-to-reference-attributes-about-the-current-node-in-xpath2-predicates