具有更长[和几乎相同] Xpath的标签数量的简写

时间:2010-03-25 07:35:48

标签: xslt xpath xpath-1.0

例如:这是一个xslt

<xsl:template match="/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_1
|/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_2
|/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_3
 .
 .
|/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_N"/>

在上面的代码中我可以使用XPath /root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4 只使用一次[使用大括号或其他]并减少代码的庞大程度?

如您所见,所有节点都是彼此的兄弟节点,因此除了它们的名称之外,它们的Xpath是相同的。有没有短手财产?

XSLT 1.0(或Xpath1.0)是否允许它?

3 个答案:

答案 0 :(得分:3)

问问自己是否真的需要长特定匹配表达式。我看到这只是一个例子,但你不必将完整路径包含在元素中,只需要尽可能多地使它明确。

此外,我提醒您self轴:

<xsl:template match="/.../dummy4/*[self::node_1 or self::node_2 ...]" />

如果名称是结构化且可预测的,您可以

<xsl:template match="/.../dummy4/*[substring-before(name(), '_') = 'node']" />

答案 1 :(得分:2)

  

XSLT 1.0(或Xpath1.0)是否允许它?

以下是正确的XPath 1.0表达式

root/sub-root/parent/child/grand_child
              /dummy1/dummy2/dummy3/dummy4
                /*
                 [starts-with(name(), 'node_')
                and
                  substring-after(name(), 'node_') >= 1
                and
                  not(substring-after(name(), 'node_') > $N)
                  ]

但是,match patterns只是所有XPath表达式的子集,并且某些限制适用于它们。特别是,在XSLT 1.0中的,它们不能包含对xsl:variable 的引用。

如果值N是静态已知的,那么将在上面的XPath表达式中替换此文字值(比如1000),因此具有有效的XSLT 1.0匹配模式。

请注意,这是一个极端情况,在任何实际情况下都不太可能需要这么长的匹配模式。根据定义,匹配模式不需要指定节点的完整路径 - 只有足够的“来自右侧子路径”,该节点将节点与具有必须由不同模板处理的相同名称的其他节点消除歧义。

因此,在大多数情况下,即使以下情况也足够

 *
 [starts-with(name(), 'node_')
and
  substring-after(name(), 'node_') >= 1
and
   not(substring-after(name(), 'node_') > {N})

 ]

其中{N}必须替换为整数文字 - $ N的实际值。

或者,在最简单的情况下(经常发生),如果有四个节点且不需要消除歧义,可以使用:

 node_1|node_2|node_3|node_4

答案 2 :(得分:1)

仅在在线xpath工具中测试过,所以不完全确定,但它应该可以正常工作

<xsl:template match="/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node()[name() = 'node_1' or name()='node_2' ... or name()='node_N']"/>

如果你想省略dummy4中没有任何节点,只需删除[..]

即可