This is a frequently made mistake. Never use XPath "! =" Operator when one or both of the operands are node-set (s).
value != node-set
by definition, is true if node n exists in node -set, so
value not equal to string(n)
Do you want to
value not equal to any node in node-set.
This can be expressed as follows:
value = node-set
true if there is at least one node n in node -set such that:
value = string(n)
Then
not(value = node-set)
true if node n does not exist in node-set, so
value = string(n)
Therefore, the following XPath expression will select the nodes you want :
/ * / * / describes [not (. = ../../*/physical/distribution/@id)
and
not (. = ../../*/implementation/distribution/@id)]
I personally would prefer to have only one node context comparison with combining two node-sets:
/ * / * / describes
[not (. = (../../*/physical/distribution/@id
|
../../*/implementation/distribution/@id
)
)
]
Please note that I do not use the abbreviation "//" . This is usually very expensive (inefficient) and should only be used if we do not know the structure of the XML document.
And, of course, the XPath expressions above should be evaluated against the following XML document (the second of them in the question):
<eml>
<datatable>
<physical>
<distribution id = "100" />
</physical>
</datatable>
<datatable>
<physical>
<distribution id = "300" />
</physical>
</datatable>
<software>
<implementation>
<distribution id = "200" />
</implementation>
</software>
<additionalMetadata>
<describes> 100 </describes>
<describes> 200 </describes>
<describes> 300 </describes>
<describes> 400 </describes>
</additionalMetadata>
</eml>
Dimitre novatchev
source share