【问题标题】:DOMDocument adds the line break between nodes where there is nothing between the nodesDOMDocument 在节点之间没有任何内容的节点之间添加换行符
【发布时间】:2016-07-11 23:45:57
【问题描述】:

如何防止DOMDocument在第一段节点后添加换行符\n?当节点之间有空间时,不添加换行符。

<?php

$text = '<p></p><p></p>';
$dom = new \DOMDocument();
$dom->loadHTML($text);
$innerHTML = "";
foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $child) {
    $innerHTML .= $dom->saveHTML($child);
}
echo json_encode($innerHTML);

上面的代码返回:

"<p><\/p>\n<p><\/p>"

那里有在线代码https://3v4l.org/UfZTG

【问题讨论】:

  • 不知道为什么,它看起来像是在任何不在文档末尾的段落之后添加了一个换行符。
  • 我记得几年前曾为这个或类似的问题而苦苦挣扎。不确定我是否解决了它,但this question 似乎有一些可能的解决方案。

标签: php domdocument


【解决方案1】:

我今天遇到了这个问题。我的用例似乎是相同的,即从元素生成“内部 HTML”字符串。因为我不想随意更改或修剪节点的空白,所以我找到了不同的解决方案。

DOMDocumentFragment 上运行DOMDocument::saveHTML(在我的测试中)似乎永远不会添加任何额外的空白。

从您的示例开始,您可以通过以下方式获取第一个 P 元素的 HTML 输出,而无需尾随 \n

$frag = $dom->createDocumentFragment();
$frag->appendChild(
    $dom->getElementsByTagName('p')->item(0)->cloneNode(true)
);
echo json_encode($dom->saveHTML($frag)); // Renders "<p><\/p>".

请注意,您必须使用DOMNode::cloneNode,否则您会将元素移动到DOMDocumentFragment 并将其从原来的位置移除。

如果您正在寻找一个内部 HTML 函数,以下应该可以工作。它将一个元素的所有子节点移动到DOMDocumentFragment,然后获取 HTML 值,并将节点放回它们所属的位置。这意味着我们不会克隆笔记,也不会在完成后更改树。

function innerHTML(\DOMElement $element): string
{
    $fragment = $element->ownerDocument->createDocumentFragment();
    while ($element->hasChildNodes()) {
        $fragment->appendChild($element->firstChild);
    }
    $html = $element->ownerDocument->saveHTML($fragment);
    $element->appendChild($fragment);
    return $html;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2015-05-17
    • 1970-01-01
    • 2017-10-19
    • 2014-02-01
    相关资源
    最近更新 更多