A simple modification to the XPath you referenced should accomplish what you need:
//*[not(normalize-space())]
foreach( $xpath->query('//*[not(normalize-space())]') as $node ) {
$node->parentNode->removeChild($node);
}
The answer in the question you linked to can be interpreted as "Match all elements that do not have a child node". metro
has five child nodes, so that XPath does not match it.
The XPath in my answer can be interpreted as "Match all elements that do not contain any non-whitespace text."
I suggest you read up on normalize-space()
if you are unfamiliar with it, but basically in this case, it produces an empty string if all the text nodes within an element are whitespace, so in the case of metro
we have:
not(normalize-space())
not(normalize-space(.)) // If no argument is specified, the context node is used.
not(normalize-space(" // normalize-space() expects a string, so the nodeset . is
// replaced with its string-value (all the text it contains).
"))
not("") // normalize-space() eliminates all leading and trailing
// whitespace.
not(false()) // not() expects a boolean, and the boolean equivalent of
// the empty string is false()
true()
Since the predicate evaluates to true()
, metro
is selected.