SimpleXML и китайский - PullRequest
       40

SimpleXML и китайский

1 голос
/ 09 июня 2011

Я занят, пытаясь обработать следующий канал RSS: Yahoo Search RSS , используя следующий код после получения данных:

$response = simplexml_load_string($data);

Однако 99% китайских символов и строк исчезают, когда я опрашиваю простой объект XML.

Я попытался преобразовать входящие данные в utf8, выполнив:

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

Но это также не помогает.

До того, как данные попадут в Simplexml_load_string, все будет в порядке.Но потом его нет.

Есть идеи?

Ответы [ 3 ]

2 голосов
/ 09 июня 2011

То, что вы описываете, звучит как проблема кодирования.Кодировка похожа на цепочку: если она повреждена в одной части обработки, данные могут быть повреждены.

Когда вы запрашиваете данные с 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 version="1.0" encoding="UTF-8" ?>.
  • Простые данные XML :
    • Проверка: поддерживает ли simple_xml UTF-8 кодировка?Результат: Да.
    • Проверка: возвращает ли simple_xml значения в кодировке UTF-8?Результат: Да и Нет. Как правило, simple_xml поддерживают свойства, содержащие текст в кодировке UTF-8, однако var_dump() экземпляра объекта simple_xml с данными xml предполагает, что он не поддерживает 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 голос
/ 09 июня 2011

Я посмотрел здесь: 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);

), я вижу китайские символы, но естьошибка разбора.

1 голос
/ 09 июня 2011

Есть много причин для проблем кодирования с PHP.Я бы проверил:

...