Удалить пустые теги из XML с помощью PHP - PullRequest
9 голосов
/ 22 декабря 2011

Вопрос

Как удалить пустые теги 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»

Спасибо!

Ответы [ 5 ]

15 голосов
/ 22 декабря 2011

Вы можете использовать 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>
6 голосов
/ 01 февраля 2014

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

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

2 голосов
/ 11 сентября 2013

Решение, которое работало с моим рабочим объектным кодом 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 ().

0 голосов
/ 22 декабря 2011

Если вам этого захочется, просто сделайте что-то вроде:

$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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...