Удалить пустые теги из XML с помощью PHP

Вопрос

Как удалить пустые теги xml в PHP?

Пример:

$value1 = "2"; $value2 = "4"; $value3 = ""; xml = '<parentnode> <tag1> ' .$value1. '</tag1> <tag2> ' .$value2. '</tag2> <tag3> ' .$value3. '</tag3> </parentnode>'; 

XML Результат:

 <parentnode> <tag1>2</tag1> <tag2>4</tag2> <tag3></tag3> // <- Empty tag </parentnode> 

Что я хочу!

  <parentnode> <tag1>2</tag1> <tag2>4</tag2> </parentnode> 

XML без пустых тегов, таких как «tag3»,

Благодаря!

Вы можете использовать XPath с предикатом not(node()) чтобы выбрать все элементы, у которых нет дочерних узлов.

 <?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(); 

печать

 <?xml version="1.0"?> <parentnode> <tag1>2</tag1> <tag2>4</tag2> <tag2>4</tag2> <tag2>4</tag2> </parentnode> 
 $dom = new DOMDocument; $dom->loadXML($xml); $elements = $dom->getElementsByTagName('*'); foreach($elements as $element) { if ( ! $element->hasChildNodes() OR $element->nodeValue == '') { $element->parentNode->removeChild($element); } } echo $dom->saveXML(); 

CodePad .

Это работает рекурсивно и удаляет узлы, которые:

  • содержат только пробелы
  • не имеют атрибутов
  • нет детских заметок
 // 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); } } 

Если вы собираетесь многого, просто сделайте что-нибудь вроде:

 $value[] = "2"; $value[] = "4"; $value[] = ""; $xml = '<parentnode>'; for($i=1,$m=count($value); $i<$m+1; $i++) $xml .= !empty($value[$i-1]) ? "<tag{$i}>{$value[$i-1]}</tag{$i}>" : null; $xml .= '</parentnode>'; echo $xml; 

В идеале, вероятно, вы должны использовать domdocument .

Решение, которое работало с моим производным объектным кодом PHP SimpleXMLElement, с помощью Xpath, было:

 /* * Remove empty (no children) and blank (no text) XML element nodes, but not an empty root element (/child::*). * This does not work recursively; meaning after empty child elements are removed, parents are not reexamined. */ foreach( $this->xml->xpath('/child::*//*[not(*) and not(text()[normalize-space()])]') as $emptyElement ) { unset( $emptyElement[0] ); } 

Обратите внимание, что не требуется использовать PHP DOM, DOMDocument, DOMXPath или dom_import_simplexml ().