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>
.
在/element[2]/[someNode]上下文中的XSLT表中,我希望获得一个数字,该数字表示/element[1]/[someNode]的距离(即/element1/[someNode]之前的兄弟姐妹数)。例如,在/元素[2]/subelement1的上下文中,我想有一些方法来得到数字2,从/元素[1]到/元素[1]/ subelement2的距离。我只需要给定节点名与
Intuitively I thought I could construct 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?
但不幸的是,这一页没有编译。我试图在XSLT中实现的目标是可能的吗?
3 个解决方案
#1
8
-
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.不能使用XSLT变量作为XPATH语句的轴,但可以在谓词筛选器中使用它。因此,如果您要匹配任何元素(例如*),然后将其限制为名称()等于变量中存储的值(例如*[name()=$nodename)的元素,那么XPATH将是有效的。
-
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.您正在构建的XPATH将返回匹配元素的值。如果您想返回多少元素匹配该模式,可以使用count()函数。
-
Your example XML has a document element
<root>
, but your XPATH does not include<root>
.示例XML有一个文档元素
,但是XPATH不包括 。
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::*)" />
#2
1
*[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.
*[name() = $nodename]可能是您想要的,而不是$nodename,但是您应该使用local-name()和namespace-uri()的值来定义两个变量,并检查例. *[local-name() = $localname和namespace-uri() = $namespaceuri),以获得选择元素的名称空间安全方法。
#3
0
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).
不幸的是,构建xpath是不可能的。xpath是静态编译;您不能动态地生成它们(或者如果您这样做,它们只是字符串,不能执行)。
However, what you can do is write a query that happens to cross-reference several values which themselves are dynamic...
但是,您可以做的是编写一个查询,该查询碰巧交叉引用了几个本身是动态的值……
#1
8
-
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.不能使用XSLT变量作为XPATH语句的轴,但可以在谓词筛选器中使用它。因此,如果您要匹配任何元素(例如*),然后将其限制为名称()等于变量中存储的值(例如*[name()=$nodename)的元素,那么XPATH将是有效的。
-
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.您正在构建的XPATH将返回匹配元素的值。如果您想返回多少元素匹配该模式,可以使用count()函数。
-
Your example XML has a document element
<root>
, but your XPATH does not include<root>
.示例XML有一个文档元素
,但是XPATH不包括 。
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::*)" />
#2
1
*[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.
*[name() = $nodename]可能是您想要的,而不是$nodename,但是您应该使用local-name()和namespace-uri()的值来定义两个变量,并检查例. *[local-name() = $localname和namespace-uri() = $namespaceuri),以获得选择元素的名称空间安全方法。
#3
0
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).
不幸的是,构建xpath是不可能的。xpath是静态编译;您不能动态地生成它们(或者如果您这样做,它们只是字符串,不能执行)。
However, what you can do is write a query that happens to cross-reference several values which themselves are dynamic...
但是,您可以做的是编写一个查询,该查询碰巧交叉引用了几个本身是动态的值……