从 php 中的 XML 中删除空元素
Remove empty elements from XML in php
假设我有这个 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())]
returnsall个元素没有非空文本内容(不需要递归)
foreach($xpath->query('//*[not(normalize-space())]') as $node ) {
$node->parentNode->removeChild($node);
}
查看 了解更多详情
解决方案
@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();
你可以用 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
其他答案中的 XPath 只有 returns 空元素 元素没有任何类型的子节点(没有元素节点,没有文本节点) , 没有什么)。要根据您的定义获取所有 空元素 ,即没有非空文本内容的元素,请尝试改用以下 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>
假设我有这个 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())]
returnsall个元素没有非空文本内容(不需要递归)
foreach($xpath->query('//*[not(normalize-space())]') as $node ) {
$node->parentNode->removeChild($node);
}
查看
解决方案
@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();
你可以用 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
其他答案中的 XPath 只有 returns 空元素 元素没有任何类型的子节点(没有元素节点,没有文本节点) , 没有什么)。要根据您的定义获取所有 空元素 ,即没有非空文本内容的元素,请尝试改用以下 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>