我已经生成了一个xml。我想删除的空节点很少
我的XML
https://pastebin.com/wzjmZChU
我想从我的xml中删除所有空节点。使用xpath我试过
$xpath = '//*[not(node())]';
foreach ($xml->xpath($xpath) as $remove) {
unset($remove[0]);
}
上面的代码工作到一定程度,但我无法删除所有空节点值。
修改
我已尝试过上面的代码,它只适用于单一级别。
答案 0 :(得分:3)
您认为没有子空//*[not(node())]
的任何元素节点都可以实现这一点。但是如果它删除了元素节点,它可能会导致额外的空节点,所以你需要一个不仅删除当前空元素节点的表达式,而且这些节点只有空的后代节点(递归)。此外,您可能希望避免删除文档元素,即使它是空的,因为这会导致文档无效。
/*
/*//*
/*//*[normalize-space(.) = ""]
/*//*[normalize-space(.) = "" and not(@*)]
/*//*[normalize-space(.) = "" and not(@* or .//*[@*])]
/*//*[normalize-space(.) = "" and not(@* or .//*[@*] or .//comment())]
/*//*[
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>