Reputation: 78200
Within an XSL sheet, I have a nodeset in a variable, $context
.
How do I properly query an attribute of the topmost node in $context? Obviously, if $context was the current node, I would just write "@attname"
, but it is not. Currently I do $context/../@attname
which is doesn't look great to me.
EDIT
Ok, the data. Here is what I see in the VS.
In case you wonder how I got this strange thing: I UNION'ed a node with it's subnodes and an attribute selected out from a different node:
<xsl:with-param name="context" select=". | ../@res" />
.
I'm not completely aware what results from this, but I can see that it works. Highlighted is the attribute I'm interested in.
Maybe that creates an attribute attached to nothing, if that makes sence at all :|
Upvotes: 0
Views: 2061
Reputation: 167716
As you have <xsl:with-param name="context" select=". | ../@res" />
the 'res' attribute is part of the node-set (XPath 1.0) or sequence (XPath 2.0) the variable named 'context' is bound to. With XPath 2.0 you could use $context/self::attribute(res)
but XPath 1.0 has no comparable expression so what you have already ($context[1]
or $context/../@res
) is all you can do in my view.
Upvotes: 0
Reputation: 338396
$context/../@attname
does not make too much sense. You can't go "up" here, as this would bring you "outside of" $context
.
If the node-set contains something like this (a single node)
<node attname="foo">
<bar />
</node>
then:
$context/@attname
If it is like this (a list of nodes):
<node attname="foo">
<bar />
</node>
<node attname="foo">
<bar />
</node>
then:
$context[1]/@attname
All of this does not work if the variable contains a result tree fragment (RTF). In this case, you need to employ an extension function called node-set()
. Most XSLT processors provide this function.
EDIT: Your variable holds a union of the current node and a naked attribute node from its parent:
<xsl:with-param name="context" select=". | ../@res" />
The result of a union will always be in document order, so even though you selected the attribute after the context node in the XPath, in the resulting node set it will come before - the parent of the context node is before the context node in document order.
You need $context[1]
to grab the attribute node, and $context[2]
to grab the other node.
I must say that this is some strange and probably unnecessary complicated use of variables. I'm sure there is a way to do this in a less painful fashion. For example you could do
<xsl:with-param name="context" select="." />
and then use $context/../@res
in the called template. That would be a lot more straight-forward than what you are trying now.
Also, if the <xsl:with-param>
you show here is part of an <xsl:call-template>
, you can drop that param entirely. When a template is called (instead of applied), then the context node does not change, passing it in is redundant.
Upvotes: 1
Reputation: 13536
In addition to tomalak's answer if you ever do need to propagate back up to the root you could try:
ancestor::*[not(..)]
Would love to hear of a situation where you might want/need this though.
Try it yourself by pasting:
//pet/ancestor::*[not(..)]
in this online Xpath test tool.
Upvotes: 0