使用 DOMDocument->saveHTML() 将实际 Unicode 字符自动转换为数值
Posted
技术标签:
【中文标题】使用 DOMDocument->saveHTML() 将实际 Unicode 字符自动转换为数值【英文标题】:The Actual Unicode Characters automatically converted to Numeric values using DOMDocument->saveHTML() 【发布时间】:2013-04-05 16:57:10 【问题描述】:我正在使用下面的函数来获取html字符串的内部html
function DOMinnerHTML($element)
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child)
$tmp_dom = new DOMDocument('1.0', 'UTF-8');
$tmp_dom->appendChild($tmp_dom->importNode($child, true));
$innerHTML .= trim($tmp_dom->saveHTML());
return $innerHTML;
我的 html 字符串也包含 unicode 字符。这是html字符串的示例
$html = '<div>Thats True. Yes it is well defined آپ مجھے تم کہہ کر پکاریں</div>';
当我使用上述功能时
$output = DOMinnerHTML($html);
输出如下
$output = '<div>Thats True. Yes it is well defined
کے۔سلطا</div>';
转换为数值的实际 unicode 字符。
我已经调试了代码,发现在DOMinnerHTML函数下面一行之前
$innerHTML .= trim($tmp_dom->saveHTML());
如果我回声
echo $tmp_dom->textContent;
它显示实际的 unicode 字符,但在保存到 $innerHTML
后,它会输出数字符号。
为什么这样做。
注意:请不要建议我使用 html_entity_decode 之类的函数将数字符号转换为真正的 unicode 字符,因为我的 html 字符串中还有用户格式化的数据,我不想转换。
注意:我也试过把
<meta http-equiv="content-type" content="text/html; charset=utf-8">
在我的 html 字符串之前,但没有区别。
【问题讨论】:
相关:***.com/questions/6573258/… 呃,有问题吗?数字字符引用应该仍然可以正常工作。好的,它们只是占用了更多的字节...... 【参考方案1】:我遇到了类似的问题。看了上面的评论,经过进一步的调查,我找到了一个非常简单的解决方案。
你所要做的就是使用html_entity_decode()
来转换saveHTML()
的输出,如下:
// Create a new dom document
$dom = new DOMDocument();
// .... Do some stuff, adding nodes, ...etc.
// the html_entity_decode function will solve the unicode issue you described
$result = html_entity_decode($dom->saveHTML();
// echo your output
echo $result;
这将确保正确显示 unicode 字符
【讨论】:
【参考方案2】:问得好,您做得很好,将问题缩小到导致事情变得混乱的一行代码!这让我能够弄清楚出了什么问题。
问题在于DOMDocument's saveHTML() function。它正在做它应该做的事情,但它的设计不是你想要的。
saveHTML() 将文档转换为“使用 HTML 格式”的字符串 - 这意味着它会为您进行 HTML 实体编码!可悲的是,这不是你想要的。 php 文档中的注释还表明 DOMDocument 不能很好地处理 utf-8 并且不能很好地处理片段(因为它会自动添加 html、doctype 等)。
只需使用另一个类即可查看此评论以获取建议的解决方案:alternative to DOMDocument
在看到许多关于某些 DOMDocument 缺点的投诉后, 例如编码处理不当和总是保存 HTML 片段 使用 、 和 DOCTYPE,我认为更好的解决方案是 需要。
所以这里是:SmartDOMDocument。你可以在 http://beerpla.net/projects/smartdomdocument/
目前主要亮点有:
SmartDOMDocument 继承自 DOMDocument,因此非常易于使用 - 只需声明一个 SmartDOMDocument 类型的对象而不是 DOMDocument 并在所有现有的基础上享受新的行为 功能(参见下面的示例)。
saveHTMLExact() - DOMDocument 有一个设计非常糟糕的“功能”,如果您正在加载的 HTML 代码不包含 和标签,它会自动添加它们(是的,没有 标志来关闭此行为)。因此,当您调用 $doc->saveHTML(),你新保存的内容现在有和 DOCTYPE 在里面。尝试使用代码片段时不是很方便 (XML 也有类似的问题)。 SmartDOMDocument 包含一个新功能 调用 saveHTMLExact() 完全符合您的要求 - 它 保存 HTML 而不会像 DOMDocument 那样添加额外的垃圾。
编码修复 - 众所周知,DOMDocument 不能正确处理编码(至少是 UTF-8)并且输出会出现乱码。 SmartDOMDocument 尝试 通过增强 loadHTML() 来解决这个问题 正确编码。这种行为对您来说是透明的 - 只需使用 像往常一样加载HTML()。
【讨论】:
感谢您的详细回答。其实你已经深入了解了我的问题。但是这个答案中给出的课程,我下载并使用了它,但存在同样的问题。即使您尝试这个 SmartDOMDocument 类的 testHTML() 函数,它也会详细说明它本身并不显示实际的 unicode 字符,而是显示数字等值 html 代码。那是我的实际问题。等待解决方案。【参考方案3】:mb_convert_encoding($html,'HTML-ENTITIES','UTF-8');
这对我有用
【讨论】:
以上是关于使用 DOMDocument->saveHTML() 将实际 Unicode 字符自动转换为数值的主要内容,如果未能解决你的问题,请参考以下文章
使用 DOMDocument PHP 获取 Xpath 父节点?
使用 DOMDocument->saveHTML() 将实际 Unicode 字符自动转换为数值