在使用DOMDocument函数进行处理之前,在PHP中修复格式错误的XML
发布时间:2020-12-13 18:28:37 所属栏目:PHP教程 来源:网络整理
导读:我需要将 XML文档加载到来自外部源的 PHP中. XML没有声明它的编码并包含非法字符,例如amp ;.如果我尝试直接在浏览器中加载XML文档,我会收到类似“在文本内容中找到无效字符”的错误,当在PHP中加载文件时,我会收到很多警告:xmlParseEntityRef:实体中没有名
我需要将
XML文档加载到来自外部源的
PHP中. XML没有声明它的编码并包含非法字符,例如& ;.如果我尝试直接在浏览器中加载XML文档,我会收到类似“在文本内容中找到无效字符”的错误,当在PHP中加载文件时,我会收到很多警告:xmlParseEntityRef:实体中没有名称,输入不是正确的UTF-8,表示编码!字节:0x9C 0x31 0x21 0x3C.
很明显,XML格式不正确,并且包含应转换为XML实体的非法字符. 这是因为XML提要由许多其他用户提供的数据组成,显然它在我获得之前没有经过验证或重新格式化. 我已经与XML feed的供应商交谈了,他们说他们正试图让内容提供商对其进行排序,但这看起来很愚蠢,因为他们应该首先验证输入. 我基本上需要修复XML纠正任何编码错误并将任何非法字符转换为XML实体,以便在使用PHP的DOMDocument函数时XML加载问题. 我的代码目前看起来像: $feedURL = '3704017_14022010_050004.xml'; $dom = new DOMDocument(); $dom->load($feedURL); 显示编码问题的示例XML文件(单击下载):feed.xml 包含尚未转换为XML实体的字符的示例XML: <?xml version="1.0"?> <feed> <RECORD> <ID>117387</ID> <ADVERTISERNAME>Test</ADVERTISERNAME> <AID>10544740</AID> <NAME>This & This</NAME> <DESCRIPTION>For one day only this is > than this.</DESCRIPTION> </RECORD> </feed>
尝试使用Tidy库,它可用于清理错误的HTML和XML
http://php.net/manual/en/book.tidy.php 一个纯PHP解决方案来修复这样的XML: <?xml version="1.0"?> <feed> <RECORD> <ID>117387</ID> <ADVERTISERNAME>Test < texter</ADVERTISERNAME> <AID>10544740</AID> <NAME>This & This</NAME> <DESCRIPTION>For one day only this is > than this.</DESCRIPTION> </RECORD> </feed> 会是这样的: function cleanupXML($xml) { $xmlOut = ''; $inTag = false; $xmlLen = strlen($xml); for($i=0; $i < $xmlLen; ++$i) { $char = $xml[$i]; // $nextChar = $xml[$i+1]; switch ($char) { case '<': if (!$inTag) { // Seek forward for the next tag boundry for($j = $i+1; $j < $xmlLen; ++$j) { $nextChar = $xml[$j]; switch($nextChar) { case '<': // Means a < in text $char = htmlentities($char); break 2; case '>': // Means we are in a tag $inTag = true; break 2; } } } else { $char = htmlentities($char); } break; case '>': if (!$inTag) { // No need to seek ahead here $char = htmlentities($char); } else { $inTag = false; } break; default: if (!$inTag) { $char = htmlentities($char); } break; } $xmlOut .= $char; } return $xmlOut; } 这是一个简单的状态机,指出我们是否在标签中,如果没有,则使用htmlentities对文本进行编码. 值得注意的是,这将是大型文件的内存需求,因此您可能希望将其重写为流插件或预处理器. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |