XSLT2: How to reference attributes about the curre

2019-05-07 16:14发布

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.)

2条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-05-07 16:44

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).

查看更多
趁早两清
3楼-- · 2019-05-07 16:52

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
查看更多
登录 后发表回答