如何在XPath 1.0中执行set操作

时间:2011-08-24 15:51:28

标签: xpath

我已经在SO和其他地方看到以下内容应该有效(这个例子直接取自O'Reilly的XSLT Cookbook):

(: intersection :)
$set1[count(. | $set2) = count($set2)]

(: difference :)
$set1[count(. | $set2) != count($set2)]

它看起来应该没问题,但是当与实际路径而不是变量一起使用时,这似乎失败了。例如,给出以下文档

<a>
  <new>
    <val>1</val>
    <val>2</val>
  </new>
  <old>
    <val>2</val>
    <val>3</val>
  </old>
</a>

和XPath表达式/a/new/val[count(. | /a/old/val)=count(/a/old/val)]/text()我希望获得节点集{ 2 },而是获得{ 1 2 }。我有什么想法吗?

2 个答案:

答案 0 :(得分:9)

节点集交集的公式使用节点标识,而不是值标识。

当且仅当count($n1|$n2) =1

时,两个节点是相同的

但是,您希望基于值标识进行交叉。

<强>解决方案

使用

/a/new/val[. = /a/old/val]

这将选择存在至少一个/a/new/val元素的任何/a/old/val,以使这两个元素的字符串值相同。

答案 1 :(得分:1)

备注该交叉点始终会导致由两个原始节点集之间的共同节点组成的单个节点集。

同样注意,具有相同名称和内容的两个节点将被视为两个不同节点。因此/a/new/val/text()/a/old/val/text()具有相同的值,但它们是完全不同的文本节点。

因此,你当前的交集:

/a/new/val[count(. | /a/old/val)=count(/a/old/val)]

应评估为空节点集,因为您正在交叉两个节点集而没有任何共同节点(count()操作永远不会匹配)。你正在做这样的事情:

/a/new/val/a/old/val =∅

虽然/a/new/a/old/preceding::new会产生new