Can I build this XPath query dynamically in XSLT?
I have a document that looks something like
<root>
<element>
<subelement1 />
<subelement2 />
</element>
<element>
<subelement2 />
<subelement1 />
</element>
</root>
In my XSLT sheet in the context of /element[2]/[someNode]
I want to get a number that represents the distance of /element[1]/[someNode]
(ie, the number of preceding siblings of /element1/[someNode]
). For example, in the context of /element[2]/subelement1
I'd like to have some way to get the number 2, the distance from /element[1]
to /element[1]/subelement2
. I only ever need the distance of the given node name from the first instance of <element>
.
Intuitively I thought I could constr开发者_StackOverflow社区uct this like
<xsl:variable name="nodename" select="name()" />
<xsl:value-of select="/element[1]/$nodename/preceding-sibling::*" />
but unfortunately this sheet doesn't compile. Is what I'm trying to achieve possible in XSLT?
You cannot use an XSLT variable as the axis of an XPATH statement, but you can use it in a predicate filter. So, if you were to match on any element (i.e.
*
) and then restrict it to elements who's name() is equal to the value stored in your variable (i.e.*[name()=$nodename]
) the XPATH will be valid.The XPATH you were constructing would return the value of the matching element. If you want to return how many elements match that pattern, you can use the
count()
function.Your example XML has a document element
<root>
, but your XPATH does not include<root>
.
This returns the number of preceding-sibling elements using the variable assigned by the context node:
<xsl:variable name="nodename" select="name()" />
<xsl:value-of select="count(/root/element[1]/*[name()=$nodename]/preceding-sibling::*)" />
You could eliminate the variable and just use:
<xsl:value-of select="count(/root/element[1]/*[name()=name(current())]/preceding-sibling::*)" />
*[name() = $nodename]
might be what you want instead of $nodename
but you should then better define two variables with the value of local-name() and namespace-uri() and check e.g. *[local-name() = $localname and namespace-uri() = $namespaceuri]
to have a namespace safe way of selecting elements.
Build xpath's is unfortunately impossible. XPaths are statically compiled; you cannot generate them on the fly (or if you do, they're just strings and cannot be executed).
However, what you can do is write a query that happens to cross-reference several values which themselves are dynamic...
精彩评论