在php中从XML中删除空元素

在php中从XML中删除空元素,php,xml,parsing,elements,Php,Xml,Parsing,Elements,假设我有这个XML,我需要删除空元素(根本不包含数据的元素),例如: 查看更多详细信息 解决方案 @manuelbc提供的xPath方法只能在子元素上工作(这意味着子元素将消失,但这些元素的父节点也将保持为空) 但是,这将以递归方式工作,直到XML文档中没有空节点为止 $doc = new DOMDocument; $doc->preserveWhiteSpace = false; $doc->loadxml('<XML STRING GOES HERE>'); $xp

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

查看更多详细信息

解决方案 @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();
$doc=新文档;
$doc->preserveWhiteSpace=false;
$doc->loadxml(“”);
$xpath=新的DOMXPath($doc);
而($notNodes=$xpath->query('//*[not(node())]')&($notNodes->length)){
foreach($notNodes作为$node){
$node->parentNode->removeChild($node);
}
}
$doc->formatOutput=true;
echo$doc->saveXML();

您可以使用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();

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

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

输出:

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

1450288800000
1449086400000

Thansk!这实际上并不能去除所有的空元素。相反,它只会删除空的子项。这意味着
将留下,但他们的孩子将离开。然而,我根据您的建议编写了一个递归函数来实现这一点,它可以工作!我将在稍后的帖子中分享。做任何更改都可以,Xpath和处理xml层次结构是一件痛苦的事情。好的方法还包括将xml转换为json。获取您想要的任何信息,并将其转换回xml。这就是我所做的。很好,很简单,在我的情况下,它非常有效。
<?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();
//*[not(normalize-space())]
<?xml version="1.0"?>
<data>
  <!-- keep oneDay -->
  <oneDay>
    <startDate>1450288800000</startDate>
    <endDate>1449086400000</endDate>
  </oneDay>
  <!-- remove range entirely -->
  <!-- remove deadline entirely -->
</data>