首先让我们定义"终端元素" (出于这个问题的特殊目的)。
通过"终端元素"我的意思是元素里面没有其他元素。
元素参考:http://www.w3schools.com/xml/xml_elements.asp
如何从XML文档/节点中移除所有空格(换行符,回车符,制表符和空格)以及"终端元素"用PHP?
规则:仅PHP本机XML解析器(无正则表达式)。
答案 0 :(得分:3)
“终端元素”(叶元素节点)之外的所有空格都在文本节点内(因为所有文本都在文本节点内)。因此,如果您获得了终端元素之外的所有文本节点,则可以从中删除所有空白字符。这已经是答案了。
让我们从XML文档中的一个文本节点中删除空格开始。
由于PHP使用UTF-8作为XML解析器的字符编码(在本例中我使用DOMDocument),preg_replace
在这里很方便,因为它知道UTF-8和空白字符是什么:
/** @var DomText $text */
$text->nodeValue = preg_replace('~\s+~u', '', $text->textContent);
这将从文本节点中删除所有空格。以下是对此的演示:
$doc = new DOMDocument();
$doc->loadXML('<root> Very Simple Demo </root>');
$text = $doc->documentElement->childNodes->item(0);
/** @var DomText $text */
$text->nodeValue = preg_replace('~\s+~u', '', $text->textContent);
$doc->save('php://output');
输出:
<?xml version="1.0"?>
<root>VerySimpleDemo</root>
正如您所看到的那样,空格字符将从属于该文档的唯一文本节点中删除。
使用更大的文档和“终端元素”,这自然更有趣,但工作方式基本相同。唯一的区别是获取不属于叶元素节点的所有文本节点。最好使用xpath查询:
//*[*]/text()
这是:所有文本节点都是包含其他元素的元素的子节点。我们使用以下XML(文件content.xml
)作为示例:
<?xml version="1.0"?>
<content>
<parent>
<child id="1">
<title>child 1</title>
<child id="1">
<title>
child 1.1 with whitespace
</title>
</child>
</child>
</parent>
</content>
它包含这样的叶元素以及具有子元素的其他元素。它也很好地显示了用于元素缩进的空白。
加载后:
$file = __DIR__ . '/content.xml';
$doc = new DOMDocument();
$doc->load($file);
执行xpath-query需要DOMXPath:
$xp = new DOMXPath($doc);
$texts = $xp->query('//*[*]/text()');
剩下的就是迭代所有这些文本节点并应用如上所述的空白删除:
foreach ($texts as $text) {
/** @var DomText $text */
$text->nodeValue = preg_replace('~\s+~u', '', $text->textContent);
}
结果是:
<?xml version="1.0"?>
<content><parent><child id="1"><title>child 1</title><child id="1"><title>
child 1.1 with whitespace
</title></child></child></parent></content>
这应该回答这个问题。但如果没有更多的冗长或一点点“但......”,它就不是XML。
请注意,xpath中的“text()
”表示所有类型的文本节点。 CDATA部分。如果CDATA部分仅包含空格,则上面的代码将空CDATA部分(“<![CDATA[]]>
”)呈现到输出中。解决这个问题的一种方法是从文档中删除空节点:
/** @var DomText $text */
$text->nodeValue = preg_replace('~\s+~u', '', $text->textContent);
if (!$text->length) {
$text->parentNode->removeChild($text);
}
然后,然后从文档中删除所有清空的文本节点。保持文档树整洁。希望这会有所帮助。
答案 1 :(得分:0)
DOMDocument::normalizeDocument可以做你想要的。
如果要标准化各个元素,可以调用DOMNode::normalize