![](/img/trans.png)
[英]PHP DOMDocument does not keep numeric presentation of HTML special characters
[英]load DOMDocument with HTML Special Characters (php)
我有一个问题,用PHP加载一个xml文件。 我使用DOMDocument,因为我需要函数getElementsByTagName
。
我用这个代码。
$dom = new DomDocument('1.0', 'UTF-8'); $dom->resolveExternals = false; $dom->load($_FILES["file"]["tmp_name"]);
<?xml version="1.0" encoding="UTF-8"?> <Data> <value>1796563</value> <value>Verliebt! ’</value> </Data>
错误信息:
警告:DOMDocument :: load()[domdocument.load]:实体'rsquo'未在/ tmp / php1VRb3N中定义,第4行/www/htdocs/bla/upload.php中第4行:
为了使用该实体,必须在DTD中定义它。 否则它是无效的XML。 如果您没有DTD,则应在使用DOM加载XML之前解码实体:
$dom->load(
html_entity_decode(
file_get_contents($_FILES["file"]["tmp_name"]),
ENT_COMPAT, 'UTF-8'));
你的XML解析器没有说谎。 这是一个无法(甚至没有格式良好)的文档,你将无法加载任何东西。
rsquo
是HTML中的预定义实体,但不是XML。 在XML文档中,如果要使用除最基本的内置实体( amp
, lt
, gt
, quot
和apos
)之外的任何内容,则必须在由<!DOCTYPE>
声明引用的DTD中定义它们。 (这就是XHTML的用法。)
您需要找出输入的来源并修复负责创建输入的内容,因为目前它根本不是XML。 使用字符引用( ’
或者只是普通文字字符'
以UTF-8编码。
作为最后的手段,如果你真的不得不接受这种格式错误的输入,你可以对文件进行令人讨厌的字符串替换:
$xml= file_get_contents($_FILES['file']['tmp_name']);
$xml= str_replace('’', '’', $xml);
$dom->loadXML(xml);
如果您需要为所有非XML HTML实体执行此操作,而不仅仅是rsquo
,这有点棘手。 你可以做一个正则表达式替换:
function only_html_entity_decode($match) {
if (in_array($match[1], array('amp', 'lt', 'gt', 'quot', 'apos')))
return $match[0];
else
return html_entity_decode($match[0], ENT_COMPAT, 'UTF-8');
}
$xml= preg_replace_callback('/&(\w+);/', 'only_html_entity_decode', $xml);
这仍然不是很好,因为它会破坏&\\w+;
任何序列&\\w+;
注释,CDATA部分和PI之类的地方内的字符,这实际上并不意味着实体引用。 但考虑到这种破坏的输入,它可能是你能做的最好的事情。
它肯定比在整个文档上调用html_entity_decode
更好,这也会弄乱任何XML实体引用,导致文档在存在的情况下中断&
或者<
。
另一个以不同方式存在问题的黑客方法是使用loadHTML()
加载文档。
在bobince的帮助下我的解决方案是:
$xml= file_get_contents($_FILES['file']['tmp_name']);
$xml= preg_replace('/&(\w+);/', '', $xml);
$dom = new DomDocument();
$dom->loadXML($xml);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.