如何防止DOMDocument转换 编码

时间:2019-12-02 22:13:30

标签: php domdocument

我正在尝试获取PHP中DOMElement的内部html。标记示例:

<div>...</div>
<div id="target"><p>Here's some &nbsp; <em>funny</em> &nbsp; text</p></div>
<div>...</div>
<div>...</div>

将上面的字符串输入变量$ html中,我正在做

$doc = new DOMDocument();
@$doc->loadHTML("<html><body>$html</body></html>");
$node = $doc->getElementById('target')
$markup = '';
foreach ($node->childNodes as $child) {
  $markup .= $child->ownerDocument->saveXML($child);
}

生成的$markup字符串如下所示(转换为JSON以显示不可见的字符):

"<p>Here's some \u00a0 <em>funny</em> \u00a0 text</p>"

所有&nbsp;个字符都已转换为unicode不间断空格,这破坏了我的应用程序。

在我理想的世界中,将有一种方法可以检索目标div 原样中的html原始字符串,而无需DOMDocument对其进行任何处理。这似乎不可能,所以下一个最好的办法就是以某种方式关闭此字符转换。到目前为止,我已经尝试过:

  • 设置$doc->substituteEntities = false;无任何结果。将其更改为true也无济于事。
  • 切换$doc->preserveWhiteSpace而没有任何改变
  • saveXML更改为saveHTML。没关系。

最后,我求助于此hack,该方法虽然有效,但感觉不到正确的解决方案。

$markup = str_replace("\xc2\xa0", '&nbsp;', $markup);

肯定有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

您可以使用mb_convert_encoding()将Unicode字符转换为它们的实体,而无需碰括号,例如:

<?php
$html = '
<div>...</div>
<div id="target"><p>Here\'s some &nbsp; <em>funny</em> &nbsp; text</p></div>
<div>...</div>
<div>...</div>
';

$doc = new DOMDocument();
libxml_use_internal_errors();
$doc->loadHTML("<html><body>$html</body></html>");
$node = $doc->getElementById('target');
$markup = '';
foreach ($node->childNodes as $child) {
  $markup .= $child->ownerDocument->saveHTML($child);
}

$markup = mb_convert_encoding($markup, 'HTML-ENTITIES', 'UTF-8');
echo $markup;

输出:

<p>Here's some &nbsp; <em>funny</em> &nbsp; text</p>