Recipe 1.6. Taming Complex Logic Using QuantifiersProblemYou need to test a sequence for the existence of a condition in some or all of its items. SolutionXPath 1.0If the condition is based on equality, then the semantics of the = and != operators in XPath 1.0 and 2.0 will suffice. (: True if at least one section is referenced. :) //section/@id = //ref/@idref (: True if all section elements are referenced by some ref element. :) count(//section) = count(//section[@id = //ref/@idref]) XPath 2.0In XPath 2.0, use some and every expressions to do the same. (: True if at least one section is referenced. :) some $id in //para/@id satisfies $id = //ref/@idref (: True if all section elements are referenced by some ref element. :) every $id in //section/@id satisfies $id = //ref/@idref However, you can go quite a bit further with less effort in XPath 2.0. (: There exists a section that references every section except itself. :) some $s in //section satisfies every $id in //section[@id ne $s/@id]/@id satisfies $id = $s/ref/@idref (: $sequence2 is a sub-sequence of $sequence1 :) count($sequence2) <= count($sequence1) and every $pos in 1 to count($sequence1), $item1 in $sequence1[$pos], $item2 in $sequence2[$pos] satisfies $item1 = $item2 If you remove the count check in the preceding expression, it would assert that at least the first count($sequence1) items in $sequence2 are the same as corresponding items in $sequence1. DiscussionThe semantics of =, !=, <, >, <=, >= in XPath 1.0 and 2.0 sometimes surprise the uninitiated when one of the operands is a sequence or XPath 1.0 node set. This is because the operators evaluate to true if there is at least one pair of values from each side of the expression which compare according to the relation. In XPath 1.0, this can sometimes work to your advantage, as we have shown previously, but other times it can leave your head spinning and you longing to be back in the 5th grade where math made sense. For example, one would guess that $x = $x should always be true, but if $x is the empty sequence, it is not! This follows from the fact that you cannot find a pair of items within each empty sequence that are equal. |