我正忙着尝试处理以下RSS提要:Yahoo Search RSS,一旦获取数据,使用以下代码:
$response = simplexml_load_string($data);
然而,当我询问简单的xml对象时,99%的汉字和字符串都消失了。
我尝试通过执行以下操作将传入数据转换为utf8:
$data = iconv("UTF-8", "UTF-8//TRANSLIT", $data);
但这也无济于事。
在数据点击simplexml_load_string之前100%罚款。但事后,它不是。
有什么想法吗?
答案 0 :(得分:2)
您所描述的内容听起来像编码问题。编码就像一个链,如果它在处理的一个部分被破坏,数据就会被破坏。
当您从RSS服务器请求数据时,您将获得特定字符编码的数据。你应该找到的第一件事是对数据的编码。
Data URL: http://tw.blog.search.yahoo.com/rss?ei=UTF-8&p=%E6%95%B8%E4%BD%8D%E6%99%82%E4%BB%A3%20%E9%9B%9C%E8%AA%8C&pvid=QAEnPXeg.ioIuO7iSzUg9wQIc1LBPk3uWh8ABnsa
根据网站标题,编码为 UTF-8 。这是标准的XML编码。
但是,如果数据不是UTF-8编码而标题是这样说的,那么您需要找到正确的数据编码并在继续之前将其带入UTF-8。
接下来要检查的是simplexml_load_string()是否能够处理UTF-8数据。
我不使用simplexml,我使用DomDocument。所以我不能说是否。不过,我建议你改用DomDocument。它肯定支持UTF-8加载,它返回的所有数据也以UTF-8编码。你应该安全地假设simplexml也能正确处理UTF-8。
链条的下一部分是您的显示器。你写的是你的数据坏了。你怎么能这么说?你如何询问simplexml对象?
正如所写,编码就像一个链。如果一个元素断开,则整体结果会被破坏。要找出它断裂的地方,每个元素都必须自己检查。你想要的编码是UTF-8。
<?xml version="1.0" encoding="UTF-8" ?>
。var_dump()
表示它不支持CDATA。 CDATA用于相关数据。 CDATA元素将被删除。此时,这看起来就像您所面临的错误。但是,您可以将所有CDATA元素转换为文本。为此,您需要在加载XML数据时指定一个选项。该选项是一个名为LIBXML_NOCDATA
的常量,它将CDATA合并为文本节点。
以下是我用于上述测试的示例代码,演示了如何使用该选项:
$data_url = 'http://tw.blog.search.yahoo.com/rss?ei=UTF-8&p=%E6%95%B8%E4%BD%8D%E6%99%82%E4%BB%A3%20%E9%9B%9C%E8%AA%8C&pvid=QAEnPXeg.ioIuO7iSzUg9wQIc1LBPk3uWh8ABnsa';
$xml_data = file_get_contents($data_url);
$inspect = 256;
echo "First $inspect bytes out of ", count($xml_data),":\n", wordwrap(substr($xml_data, 0, $inspect)), "\n";
echo "UTF-8 test: ", var_dump(can_be_valid_utf8_statemachine($xml_data)), "\n";
$simple_xml = simplexml_load_string($xml_data, null, LIBXML_NOCDATA);
var_dump($simple_xml);
/**
* Bitwise check a string if it would validate
* as utf-8.
*
* @param string $str
* @return bool
*/
function can_be_valid_utf8_statemachine( $str ) {
$length = strlen($str);
for ($i=0; $i < $length; $i++) {
$c = ord($str[$i]);
if ($c < 0x80) $n = 0; # 0bbbbbbb
elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
else return false; # Does not match
for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
return false;
}
}
return true;
}
我认为这会解决您的问题。如果不是DomDocument能够处理CDATA元素。由于编码链未经过进一步测试,您可能仍会在进一步处理数据时遇到编码问题,因此请注意保持编码直至输出。
答案 1 :(得分:1)
PHP的编码问题有很多原因。我查一下:
答案 2 :(得分:1)
我看了一眼: Simplexml_load_string() fail to parse error 做完后说的话(
$data = file_get_contents('http://tw.blog.search.yahoo.com/rss?ei=UTF-8&p=%E6%95%B8%E4%BD%8D%E6%99%82%E4%BB%A3%20%E9%9B%9C%E8%AA%8C&pvid=QAEnPXeg.ioIuO7iSzUg9wQIc1LBPk3uWh8ABnsa');
$data = iconv("GB18030", "utf-8", $data);
$response = simplexml_load_string($data);
) 我可以看到中文字符,但是有一个解析错误。