Reputation: 3637
I have used this solution to remove empty tags from my generated XML.
Remove empty tags from a XML with PHP
However, if the generated XML has nested nodes that are empty, for example:
<metro>
<distance></distance>
<name></name>
</metro>
Then the result for that portion will be
<metro/>
Is there a way to remove those self-closing tags?
Upvotes: 1
Views: 1897
Reputation: 101730
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.
Upvotes: 3
Reputation: 11416
Don't know if you can use it in your setup but with the XPath-Expression
/*/metro/*[normalize-space()]/parent::*
you would only get metro-nodes with children that are not empty.
Upvotes: 1