我正在尝试获取DOMElementPHP 中 a 的内部 HTML。标记示例:
<div>...</div>
<div id="target"><p>Here's some <em>funny</em> text</p></div>
<div>...</div>
<div>...</div>
Run Code Online (Sandbox Code Playgroud)
将上面的字符串输入变量中$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);
}
Run Code Online (Sandbox Code Playgroud)
生成的$markup字符串如下所示(转换为 JSON 以显示不可见字符):
"<p>Here's some \u00a0 <em>funny<\/em> \u00a0 text<\/p>"
Run Code Online (Sandbox Code Playgroud)
所有 字符都已转换为 Unicode 不间断空格,这会破坏我的应用程序。
在我的理想世界中,有一种方法可以按原样检索目标 div 内的原始 HTML 字符串,而无需DomDocument对其执行任何操作。这似乎不可能,所以下一个最好的办法是以某种方式关闭此字符转换。到目前为止我已经尝试过:
$doc->substituteEntities = false;没有结果。更改为true也没有帮助。$doc->preserveWhiteSpace方式均无变化saveXML为saveHTML. 没有什么区别。最后我求助于这个 hack,它有效,但感觉不是正确的解决方案。
$markup = str_replace("\xc2\xa0", ' ', $markup);
Run Code Online (Sandbox Code Playgroud)
当然有更好的方法吗?
您可以使用非常神秘的函数mb_encode_numericentity()来转换可见 ASCII 范围之外的这些字符,因此它不会影响您的标记等:
<?php
$html = <<< HTML
<div>...</div>
<div id="target"><p>Here's some <em>funny </em> text</p></div>
<div>...</div>
<div>...</div>
HTML;
$doc = new DOMDocument();
libxml_use_internal_errors();
$doc->loadHTML("<html><head><meta charset=UTF-8></head><body>$html</body></html>");
$node = $doc->getElementById('target');
$markup = '';
foreach ($node->childNodes as $child) {
$markup .= $child->ownerDocument->saveHTML($child);
}
$convmap = [
0x00, 0x1f, 0, 0xff,
0x7f, 0x10ffff, 0, 0xffffff,
];
$markup = mb_encode_numericentity($markup, $convmap, "UTF-8");
echo $markup;
Run Code Online (Sandbox Code Playgroud)
输出:
<p>Here's some   <em>funny 😂</em>   text</p>
Run Code Online (Sandbox Code Playgroud)
超出了原始问题的范围,但我也在字符串中添加了表情符号。要对多字节字符进行编码,<meta charset="UTF-8">将强制 PHP 将内容视为 Unicode,而不是默认的 ISO-8859-1。
| 归档时间: |
|
| 查看次数: |
1226 次 |
| 最近记录: |