我需要将
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实体的字符的示例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
http://php.net/manual/en/book.tidy.php
<?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对文本进行编码.