SimpleXML 和中文

发布于 2024-11-14 13:32:40 字数 545 浏览 2 评论 0原文

我正忙于处理以下 RSS 提要:Yahoo Search RSS,获取数据后使用以下代码:

$response = simplexml_load_string($data);

但是,99% 的中文字符和字符串当我询问简单的 xml 对象时消失。

我尝试通过执行以下操作将传入数据转换为 utf8:

$data = iconv("UTF-8", "UTF-8//TRANSLIT", $data);

但这也没有帮助。

在数据到达 simplexml_load_string 之前,它 100% 正常。但后来就不是了。

有什么想法吗?

I'm busy trying to process the following RSS feed: Yahoo Search RSS, using the following code once the data is fetched:

$response = simplexml_load_string($data);

However, 99% of the chinese characters and strings disappear when I interrogate the simple xml object.

I've tried converting the incoming data to utf8 by doing:

$data = iconv("UTF-8", "UTF-8//TRANSLIT", $data);

But this also doesn't help.

Before the data hits simplexml_load_string its 100% fine. But afterwards, its not.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

还在原地等你 2024-11-21 13:32:40

你所描述的听起来像是编码问题。编码就像一条链条,如果在处理过程中的某个部分被破坏,数据就会被损坏。

当你向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。

  • 输入数据:所有检查正常:
  • 检查:编码数据似乎是UTF-8?结果:是的。从给定的数据 URL 获取的输入数据确实验证了 UTF-8 编码。这可以用提供的数据进行正确的测试。
  • 检查:原始 xml 数据是否将自身标记为 UTF-8 编码?结果:是的。这可以在第一个字节内进行验证:
  • 简单XML数据
  • 检查:simple_xml是否支持UTF-8编码?结果:是的。
  • 检查:simple_xml 是否返回 UTF-8 编码的值?结果:是和否。通常 simple_xml 支持包含 UTF-8 编码文本的属性,但是带有 xml 数据的 simple_xml 对象实例的 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 元素。由于编码链没有经过进一步测试,在进一步处理数据时您可能仍然会遇到编码问题,因此请注意将编码保持在输出中。

What you describe sounds like an encoding issue. Encoding is like a chain, if it get's broken at one part of the processing, the data can be damaged.

When you request the data from the RSS server, you will get the data in a specific character encoding. The first thing you should find out is the encoding of that data.

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

According to the website headers, the encoding is UTF-8. This is the standard XML encoding.

However if the data is not UTF-8 encoded while the headers are saying so, you need to find out the correct encoding of the data and bring it into UTF-8 before you go on.

Next thing to check is if simplexml_load_string() is able to deal with UTF-8 data.

I do not use simplexml, I use DomDocument. So I can not say if or not. However I can suggest you to use DomDocument instead. It definitely supports UTF-8 for loading and all data it returns is encoded in UTF-8 as well. You should safely assume that simplexml handles UTF-8 properly as well however.

Next part of the chain is your display. You write that your data is broken. How can you say so? How do you interrogate the simplexml object?


Revisiting the Encoding Chain

As written, encoding is like a chain. If one element breaks, the overall result is damaged. To find out where it breaks, each element has to be checked on it's own. The encoding you aim for is UTF-8 here.

  • Input Data: All Checks OK:
  • Check: Does the encoding data seems to be UTF-8? Result: Yes. The input data aquired from the data URL given, does validate the UTF-8 encoding. This could be properly tested with the data provided.
  • Check: Does the raw xml data mark itself as being UTF-8 encoded? Result: Yes. This could be verified within the first bytes that are: <?xml version="1.0" encoding="UTF-8" ?>.
  • Simple XML Data:
  • Check: Does simple_xml support the UTF-8 encoding? Result: Yes.
  • Check: Does simple_xml return values in the UTF-8 encoding? Result: Yes and No. Generally simple_xml support properties containing text that is UTF-8 encoded, however a var_dump() of the simple_xml object instance with the xml data suggests that it does not support CDATA. CDATA is used in the data in question. CDATA elements will get dropped.

At this point this looks like the error you are facing. However you can convert all CDATA elements into text. To do this, you need to specify an option when loading the XML data. The option is a constant called LIBXML_NOCDATA and it will merge CDATA as text nodes.

The following is an example code I used for the tests above and demonstrates how to use the option:

$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; 
}

I assume that this will fix your issue. If not DomDocument is able to handle CDATA elements. As the encoding chain is not further tested, you might still get encoding issues in the further processing of the data, so take care that you keep the encoding up to the output.

亣腦蒛氧 2024-11-21 13:32:40

我在这里看了一下:
Simplexml_load_string() 无法解析错误
按照它所说的去做之后(

 $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);


我可以看到中文字符,但出现解析错误。

I took a look here:
Simplexml_load_string() fail to parse error
And after doing what it says (

 $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);

)
I can see the Chinese characters, but there is a parse error.

剩余の解释 2024-11-21 13:32:40

PHP 编码问题的原因有很多。我会检查:

There are a lot of reasons for encoding issues with PHP. I'd check:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文