PHP DOMDocument 在追加子元素时错过分界线

PHP DOMDocument miss breakline when appending child element

我试图恢复 XML 文件并添加一个新元素,但它似乎错过了最后的 '\n'。

比如原文件是这样的

$doc = new DOMDocument;
$doc->formatOutput = true;
$node = $doc->createElement("root");
$ele = $doc->createElement("first-ele", 'ele1');
$node->appendChild($ele);
$ele2 = $doc->createElement("sec-ele", 'ele2');
$node->appendChild($ele2);
$doc->appendChild($node);
$data_string = $doc->saveXML();
echo $doc->saveXML();

输出很好。

<?xml version="1.0"?>
<root>
  <first-ele>ele1</first-ele>
  <sec-ele>ele2</sec-ele>
</root>

但是,我想在根标签中添加一个新元素。

$new_doc = new DOMDocument;
$new_doc->loadXML($data_string);
$new_doc->formatOutput = true;
$root = $new_doc->getElementsByTagName('root')->item(0);
$new_element = $new_doc->createElement('third-ele', 'third');
$root->appendChild($new_element);
echo $new_doc->saveXML();

输出似乎错过了隔断线。

<?xml version="1.0"?>
<root>
  <first-ele>ele1</first-ele>
  <sec-ele>ele2</sec-ele>
<third-ele>third</third-ele></root>

演示~https://3v4l.org/PFk10

解析器默认保留空格。它们被放入文本节点。 root 元素节点实际上有五个子节点。换行符和缩进的两个元素和三个文本节点。

现在您要在最后一个空白文本节点之后添加第三个元素节点。序列化程序识别混合类型的子节点并且不添加额外的空格(它们可以 change/break 含义:<first-char>W</first-char>ord vs <first-char>W</first-char> ord)。

这是一个 属性 DOMDocument::preserveWhiteSpace,您可以在加载 XML 之前将其设置为 false。在这种情况下,解析器不会创建任何空白文本节点,子节点也不会是混合类型。

$new_doc = new DOMDocument;
$new_doc->preserveWhiteSpace = false;
$new_doc->loadXML($data_string);
$new_doc->formatOutput = true;
$root = $new_doc->documentElement;
$new_element = $new_doc->createElement('third-ele', 'third');
$root->appendChild($new_element);
echo $new_doc->saveXML();