contains
is a string function, that checks if the first string contains the second string (or if you like, if the second string is a substring of the first). Where an argument to a string function is a node (like Name
) it will get the string value of that node to use. It is not used to check if a node contains a specific child node.
So, Name[contains(.,abc)]
is saying "Does the string value of the Name
element contain the string value of the child abc
element?"
This is an odd thing to do, because it will always be true for all Name
elements. The string value of a node includes the text of all descendants. And if there was no child abc
, the string value would be an empty string, and so the expression would still be true.
For example, if the node was <Name>1<abc>2</abc></Name>
the string value of Name
would be "12", which obviously contains the string value of abc
, which is "2".
On the other hand Name[abc]
is getting the Name
element if a child abc
exists, regardless of what the string value is. Thus it would match <Name><abc /></Name>
but not <Name/>
.
(It's possible, the first expression should be Name[contains(.,'abc')]
, in which case it would match Name
elements which contained the string "abc". Thus it would match <Name>abcdef</Name>
but not <Name>cdefgh</Name>
)