I have the following XML,
<Root>
<Node>
<Child>ch</Child>
<Child>ch1</Child>
</Node>
<Node>
<Child>ch2</Child>
<Child>ch3</Child>
</Node>
I want to check if all the nodes in the XML have at least one child node. If I use boolean(//Node/Child) it will check the whole XML and won't complain if any Node doesn't. have a Child node. If I use a predicate to mention the position, it works - boolean(//Node[1]/Child).
Thanks Sugata
CodePudding user response:
A solid XPath-2.0 solution would be using a quantified expression like this:
every $x in /Root/Node satisfies count($x/*)
Here the fact is used that all values greater than zero for the count(...)
function are interpreted as TRUE. Explicitly, it would be count($x/*) > 0
.
CodePudding user response:
It's possible by counting Nodes
with a Child
count equal to zero
not(count(//Node[count(Child) = 0]) > 0)
Given
<Root>
<Node>
<Child>ch</Child>
<Child>ch1</Child>
</Node>
<Node>
<Child>ch2</Child>
<Child>ch3</Child>
</Node>
<Node/>
</Root>
Test failed, there are empty Node
elements. In other words, the count of empty elements is greater than zero.
xmllint --xpath 'not(count(//Node[count(Child) = 0]) > 0)' test.xml; echo
false
Removing <Node/>
xmllint --xpath 'not(count(//Node[count(Child) = 0]) > 0)' test.xml; echo
true
If 2 empty node exist
xmllint --xpath 'count(//Node[count(Child) = 0])' test.xml; echo
2