我可以在XSLT中动态构建这个XPath查询吗?

时间:2021-09-11 23:10:39

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  

  1. 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将是有效的。

  2. 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()函数。

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

  1. 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将是有效的。

  2. 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()函数。

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

但是,您可以做的是编写一个查询,该查询碰巧交叉引用了几个本身是动态的值……