如何在XPath-1.0中进行集合运算?

问题描述 投票:0回答:2

我在 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 }
。有什么想法我做错了吗?

xml xpath xslt xslt-1.0 xpath-1.0
2个回答
12
投票

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

两个节点相同当且仅当

count($n1|$n2) =1

但是,您希望根据值标识进行相交。

解决方案

使用

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

这会选择任何至少存在一个

/a/new/val
元素的
/a/old/val
,使得这两个元素的字符串值相同。


2
投票

备注,交集始终会产生由两个原始节点集之间的共同节点组成的单个节点集。

另请注意,具有相同名称和内容的两个节点将被视为两个不同节点。因此

/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

© www.soinside.com 2019 - 2024. All rights reserved.