Remove empty tags from a XML with PHP

You can use XPath with the predicate not(node()) to select all elements that do not have child nodes.

<?php
$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->loadxml('<parentnode>
    <tag1>2</tag1>
    <tag2>4</tag2>
    <tag3></tag3>
    <tag2>4</tag2>
    <tag3></tag3>
    <tag2>4</tag2>
    <tag3></tag3>
</parentnode>');

$xpath = new DOMXPath($doc);

foreach( $xpath->query('//*[not(node())]') as $node ) {
    $node->parentNode->removeChild($node);
}

$doc->formatOutput = true;
echo $doc->savexml();

prints

<?xml version="1.0"?>
<parentnode>
  <tag1>2</tag1>
  <tag2>4</tag2>
  <tag2>4</tag2>
  <tag2>4</tag2>
</parentnode>

This works recursively and removes nodes that:

  • contain only spaces
  • do not have attributes
  • do not have child notes
// not(*) does not have children elements
// not(@*) does not have attributes
// text()[normalize-space()] nodes that include whitespace text
while (($node_list = $xpath->query('//*[not(*) and not(@*) and not(text()[normalize-space()])]')) && $node_list->length) {
    foreach ($node_list as $node) {
        $node->parentNode->removeChild($node);
    }
}

Tags:

Php

Xml

Tags