PHP从XML中删除空节点值

时间:2017-04-17 12:14:49

标签: php xml xpath

我已经生成了一个xml。我想删除的空节点很少

我的XML

https://pastebin.com/wzjmZChU

我想从我的xml中删除所有空节点。使用xpath我试过

$xpath = '//*[not(node())]';
foreach ($xml->xpath($xpath) as $remove) {
    unset($remove[0]);
}

上面的代码工作到一定程度,但我无法删除所有空节点值。

修改

我已尝试过上面的代码,它只适用于单一级别。

1 个答案:

答案 0 :(得分:3)

您认为没有子空//*[not(node())]的任何元素节点都可以实现这一点。但是如果它删除了元素节点,它可能会导致额外的空节点,所以你需要一个不仅删除当前空元素节点的表达式,而且这些节点只有空的后代节点(递归)。此外,您可能希望避免删除文档元素,即使它是空的,因为这会导致文档无效。

构建表达式

  • 选择文档元素
    /*
  • 文档元素的任何后代
    /*//*
  • ...只有空格作为文字内容(包括后代)
    /*//*[normalize-space(.) = ""]
  • ...并且没有属性
    /*//*[normalize-space(.) = "" and not(@*)]
  • ...或属性为/*//*[normalize-space(.) = "" and not(@* or .//*[@*])]
  • 的后代
  • ...或评论
    /*//*[normalize-space(.) = "" and not(@* or .//*[@*] or .//comment())]
  • ...或者pi /*//*[ normalize-space(.) = "" and not(@* or .//*[@*] or .//comment() or .//processing-instruction()) ]

放在一起

以相反的顺序迭代结果,以便在父项之前删除子节点。

$xmlString = <<<'XML'
<foo>
  <empty/>
  <empty></empty>
  <bar><empty/></bar>
  <bar attr="value"><empty/></bar>
  <bar>text</bar>
  <bar>
   <empty/>
   text
  </bar>
  <bar>
   <!-- comment -->
  </bar>
</foo>
XML;

$xml = new SimpleXMLElement($xmlString);

$xpath = '/*//*[
  normalize-space(.) = "" and
  not(
    @* or 
    .//*[@*] or 
    .//comment() or
    .//processing-instruction()
  )
]';
foreach (array_reverse($xml->xpath($xpath)) as $remove) {
  unset($remove[0]);
}

echo $xml->asXml();

输出:

<?xml version="1.0"?>
<foo>



  <bar attr="value"/>
  <bar>text</bar>
  <bar>

   text
  </bar>
  <bar>
   <!-- comment -->
  </bar>
</foo>
相关问题