Alex Rivera | Logout

How to perform set operations in XPath-1.0?

Asked 2011-08-24T15:51:27.990
14

I've seen on SO and other places that the following is supposed to work (this example is lifted directly from O'Reilly's XSLT Cookbook):

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

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

and it looks like it should be OK, however this seems to fail when used with actual paths rather than variables. For example, given the following document

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

and the XPath expression /a/new/val[count(. | /a/old/val)=count(/a/old/val)]/text() I would expect to get the node-set { 2 } but instead am getting { 1 2 }. Any ideas what I'm doing wrong?

Edit
Report

1 Answer

2

Remark that intersection always results in a single node-set composed by the nodes in common between the two original nodes-sets.

Also note that two nodes with same name and content are to be treated as two distinct nodes. Thus /a/new/val/text() and /a/old/val/text() have same value but they are completely distinct text nodes.

Thus your current intersection:

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

should evaluate to an empty node-set, because you are intersecting two nodes-sets without any node in common (count() operation will never match). You are doing something like this:

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

While /a/new ∩ /a/old/preceding::new will produce new.

answered 2011-08-24T17:14:00.987

Your Answer