我有一个问题,用PHP加载一个xml文件。我使用DOMDocument,因为我需要函数getElementsByTagName
我用这个代码。
$dom = new DomDocument('1.0', 'UTF-8');
$dom->resolveExternals = false;
$dom->load($_FILES["file"]["tmp_name"]);
$dom = new DomDocument('1.0', 'UTF-8');
$dom->resolveExternals = false;
$dom->load($_FILES["file"]["tmp_name"]);
的ErrorMessage:
警告:DOMDocument :: load()[domdocument.load]:实体'rsquo'未在/ tmp / php1VRb3N中定义,第4行/www/htdocs/bla/upload.php中第4行
答案 0 :(得分:2)
为了使用该实体,必须在DTD中定义它。否则它是无效的XML。如果您没有DTD,则应在使用DOM加载XML之前对实体进行解码:
$dom->load(
html_entity_decode(
file_get_contents($_FILES["file"]["tmp_name"]),
ENT_COMPAT, 'UTF-8'));
答案 1 :(得分:1)
您的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);
这仍然不是很好,因为它会在评论,CDATA部分和PI之类的地方发送任何&\w+;
字符序列,这实际上并不意味着实体引用。但考虑到这种破坏的输入,它可能是你能做的最好的事情。
这肯定比在整个文档上调用html_entity_decode
更好,这也会弄乱任何XML实体引用,导致文档在存在&
或<
时中断。 / p>
另一个以不同方式存在疑问的黑客是使用loadHTML()
加载文档。
答案 2 :(得分:0)
在bobince的帮助下我的解决方案是:
$xml= file_get_contents($_FILES['file']['tmp_name']);
$xml= preg_replace('/&(\w+);/', '', $xml);
$dom = new DomDocument();
$dom->loadXML($xml);