Как выполнять заданные операции в XPath 1.0
Я видел в SO и других местах, что должно работать следующее (этот пример снят непосредственно из Cookbook от O'Reilly XSLT):
(: 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()
Я ожидаю получить node -set { 2 }
, но вместо этого получаю { 1 2 }
. Любые идеи, что я делаю неправильно?
Ответы
Ответ 1
Формулы для пересечения node -set используют node -тождество, а не значение.
Два узла идентичны тогда и только тогда, когда count($n1|$n2) =1
Однако вы хотите пересечься на основе идентификатора значения.
Решение
Использование
/a/new/val[. = /a/old/val]
это выбирает любой /a/new/val
, для которого существует хотя бы один элемент /a/old/val
, так что строковые значения этих двух элементов одинаковы.
Ответ 2
Примечание, что пересечение всегда приводит к одному набору node, составленному узлами в общем между двумя исходными наборами узлов.
Также отметить, что два узла с одинаковым именем и содержимым должны рассматриваться как два различных узла. Таким образом, /a/new/val/text()
и /a/old/val/text()
имеют одинаковое значение, но они являются полностью различными текстовыми узлами.
Таким образом, ваше текущее пересечение:
/a/new/val[count(. | /a/old/val)=count(/a/old/val)]
должен вычисляться до пустого node -set, потому что вы пересекаете два набора узлов без какого-либо node общего (операция count()
никогда не будет соответствовать). Вы делаете что-то вроде этого:
/a/new/val
∩ /a/old/val
= ∅
While /a/new
∩ /a/old/preceding::new
will produce new
.