📜 ⬆️ ⬇️

Check of equality, inequality, identity of nodes in XPath

On the one hand, in the XPath language, familiar to each programmer is used the comparison operators "equal", "not equal", "less", "more" and others. On the other hand, these operators can work not only with primitive types, but also with whole sets of nodes. Ignorance of the rules for comparing node sets can lead to some surprises.

Try to quickly answer the question, what is the following expression:

foo = 'bar' and foo != 'bar'

If your answer is false , the author suggests read more.
')

Comparing Node to String


A simple task: check if the foo attribute is equal to the string 'bar' :

@foo = 'bar'

When solving the inverse problem, quite often you can see the following code:

@foo != 'bar'

In most cases, this code works as expected. However, in the case where the foo attribute is missing, this expression returns false . If you carefully read the documentation and translate @foo != 'bar' into Russian, you get the following: there is at least one attribute foo that is not equal to 'bar' . In the absence of the foo attribute, the condition is not met, hence false .

The correct solution of the problem:

not(@foo = 'bar')

What is translated into Russian means: there is not a single attribute foo , equal to 'bar' .

Comparing node set with string


Take the following document:
<list>
<item>foo</item>
<item>bar</item>
<item>baz</item>
</list>


Let us apply various combinations of operators of equality, inequality and negation:
ExpressionTransferResult
item = 'foo'There is at least one element equal to 'foo' .true
item != 'bar'There is at least one element not equal to 'bar' .true
not(item = 'foo')There is not a single element equal to 'foo' .false
not(item != 'baz')All available elements are equal to 'baz' .false
As you can see, it is possible that the expression item = 'foo' and item != 'foo' returns true .

Verify node identity


When comparing the two nodes, they are reduced to a string. What if you need to check not the coincidence of the string representation, but the identity? In other words, it is necessary to establish that the two nodes being checked are the same node. Such a task, for example, is found in the Münch grouping .

The first solution is pure XPath:

count($foo | $bar) = 1

This expression uses the property of the union operator , which consists in the fact that the same node cannot enter into the result of an operation twice. If the result is a single node, then the source nodes are identical.

The second solution uses the generate-id XSLT function:

generate-id($foo) = generate-id($bar)

This function by definition returns the same result for the same node. If the results of the function are equal, then the source nodes are identical.

Comments and additions are welcome.

Source: https://habr.com/ru/post/70181/


All Articles