'Check existence of a node under a repeating node in XML using Xpath
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
Solution 1:[1]
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
Solution 2:[2]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | zx485 |
