【问题标题】:Remove empty elements from XML in php从 php 中的 XML 中删除空元素
【发布时间】:2015-12-02 21:39:02
【问题描述】:

假设我有这个 XML,我需要删除空元素(根本不包含数据的元素),例如:

...
<date>
    <!-- keep oneDay -->
    <oneDay>
        <startDate>1450288800000</startDate>
        <endDate>1449086400000</endDate>
    </oneDay>
    <!-- remove range entirely -->
    <range>
        <startDate/>
        <endDate/>
    </range>
    <!-- remove deadline entirely -->
    <deadline>
        <date/>
    </deadline>
<data>
...

那么输出应该是

...
<oneDay>
    <startDate>1450288800000</startDate>
    <endDate>1449086400000</endDate>
</oneDay>
...

我正在寻找一种动态解决方案,无论元素的字面名称如何,它都可以适用于任何此类情况。

解决方案(更新)

事实证明,使用//*[not(normalize-space())] 返回的所有 元素没有非空文本内容(无需递归)。

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

查看@har07's solution了解更多详情

解决方案

@manuelbc 提供的 xPath 方法有效,但仅适用于子元素(这意味着子元素将消失,但它们的父节点将保持...为空)。

但是,这将递归地工作,直到 XML 文档没有空节点为止。

$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->loadxml('<XML STRING GOES HERE>');

$xpath = new DOMXPath($doc);

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

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

【问题讨论】:

    标签: php xml parsing elements


    【解决方案1】:

    你可以用 XPath 做到这一点

    <?php
    $doc = new DOMDocument;
    $doc->preserveWhiteSpace = false;
    $doc->loadxml('<date>
        <!-- keep oneDay -->
        <oneDay>
            <startDate>1450288800000</startDate>
            <endDate>1449086400000</endDate>
        </oneDay>
        <!-- remove range entirely -->
        <range>
            <startDate/>
            <endDate/>
        </range>
        <!-- remove deadline entirely -->
        <deadline>
            <date/>
        </deadline>
    <data>');
    
    $xpath = new DOMXPath($doc);
    
    foreach( $xpath->query('//*[not(node())]') as $node ) {
        $node->parentNode->removeChild($node);
    }
    
    $doc->formatOutput = true;
    echo $doc->savexml();
    

    在此处查看原始解决方案: Remove empty tags from a XML with PHP

    【讨论】:

    • 谢谢!这实际上不会摆脱所有的空元素。相反,它只会删除空的孩子。意思是&lt;rage/&gt;&lt;deadline/&gt; 会留下,但他们的孩子会离开。
    • 但是,我使用您的建议编写了一个递归函数来执行此操作,并且它有效!我很快就会在帖子中分享它。随意进行任何更改。
    • Xpath 和处理 xml 层次结构很痛苦。好的方法还包括将您的 xml 转换为 json。随心所欲,并将其转换回 xml。我就是这样做的。
    【解决方案2】:

    另一个答案中的 XPath 仅返回 空元素,因为该元素没有任何类型的子节点(没有元素节点,没有文本节点,什么都没有)。要根据您的定义获取所有 空元素,即没有非空文本内容的元素,请尝试改用以下 XPath:

    //*[not(normalize-space())]
    

    eval.in demo

    输出:

    <?xml version="1.0"?>
    <data>
      <!-- keep oneDay -->
      <oneDay>
        <startDate>1450288800000</startDate>
        <endDate>1449086400000</endDate>
      </oneDay>
      <!-- remove range entirely -->
      <!-- remove deadline entirely -->
    </data>
    

    【讨论】:

    • 这一款真的很不错,很简单,在我的情况下效果很好。
    猜你喜欢
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 2016-08-26
    相关资源
    最近更新 更多