Чтение значений UTF-16 (или UTF-8) из XML и отображение результатов с помощью PHP - PullRequest
0 голосов
/ 29 января 2010

У меня много проблем со значениями Unicode (UTF-16) и PHP / XML. Я хочу прочитать набор значений Unicode из XML и вывести правильные глифы в браузер. Я пробовал с UTF-8, и у меня та же проблема.

Это простой рабочий пример, который я использовал для моего первого теста:

$text = "\x00\x41";

$text = mb_convert_encoding($text, "ASCII", "UTF-16");

echo $text;

Вывод вышеуказанного кода:

A

Однако, когда я пытаюсь получить значения из XML, вещи перестают работать.

XML:

<glyphs>
    <code>0041</code>
    <code>0042</code>
    <code>0043</code>
    <code>0044</code>
    <code>0045</code>
    <code>0046</code>
</glyphs>

В php я читаю каждое значение из приведенного выше xml, разбиваю на пары и форматирую, например, \ x00 \ x41 и т. д.

PHP:

// load xml
$xml = simplexml_load_file('encoding.xml');

if ($xml) {

    // get families
    foreach($xml->children() as $item) {

        $pairs = str_split($item, 2);

        $hex = "\x" . $pairs[0] . "\x" . $pairs[1];

        // check value...
        echo $hex . '<br/>';

        $text = mb_convert_encoding($hex, "ASCII", "UTF-16");

        echo $text;
    }

}
else {
    return 'The input is malformed.';
}

Вывод в браузере:

\x00\x41
????
\x00\x42
????
\x00\x43
????
\x00\x44
????
\x00\x45
????
\x00\x46
????

Вопросительные знаки должны быть A, B, C, D, E, F.

Что я делаю не так?

Спасибо.

Ответы [ 3 ]

1 голос
/ 29 января 2010

"\ x00" - это шестнадцатеричное обозначение внутри строки, которое обрабатывается в время компиляции .
Я думаю, что когда вы используете «\ x» + «00», компилятор сначала пытается выяснить, что такое «\ x» (я понятия не имею, каков результат), и только потом объединяет «00», поэтому результат это не то, что вы ожидаете.

Может быть, этот вопрос может помочь, хотя он в Java -> Java: преобразовать строку "\ uFFFF" в char

РЕДАКТИРОВАТЬ: просто следит за комментарием. Размещение литерала "\ x41" в вашем xml тоже не поможет, потому что тогда вы читаете строку из 4 символов.
Таким образом, ваша проблема может быть сформулирована следующим образом: как преобразовать строковое представление числовых значений в шестнадцатеричном формате в один символ, используя UTF-16. Это та же проблема, что и в приведенном выше вопросе, за исключением того, что вы хотите сделать это в php, а не в Java.

1 голос
/ 29 января 2010

Ваша тестовая программа записывает для каждого тестового символа несколько символов ASCII, за которыми следует «
» в ASCII, за которым следуют два байта UTF-16. Это не сработает. Файл должен использовать только одну кодировку символов за раз.

Сначала перепишите свой скрипт, чтобы преобразовать все выходные данные в UTF-16 (или что-то еще).

Во-вторых, кажется, что ваш браузер интерпретирует ваш файл смешанного кодирования как нечто отличное от UTF-16, возможно, ISO 8859-1 или Windows Latin 1, которые являются стандартными значениями по умолчанию. Маловероятно, что браузер будет интерпретировать файл как UTF-16 , если не указано явно (в заголовке HTTP или метатеге типа контента ). Если вы не указали тип содержимого (проверьте, отправляет ли ваш веб-сервер по умолчанию), некоторые браузеры пытаются угадать кодировку. Я сомневаюсь, что кто-нибудь может предположить, что ваш смешанный файл был UTF-16.

Не ожидайте, что все будет работать так, как вы хотите, пока не убедитесь, что браузер интерпретирует файл в соответствии с указанным типом контента.

Наконец, я рекомендую использовать iconv вместо mb_convert_encoding. iconv лучше поддерживается и имеет более широкий набор поддерживаемых кодировок.

0 голосов
/ 29 января 2010

Правильно ли вы устанавливаете вывод в заголовке?

header('Content-Type: text/html; charset=utf-8');

... а также в заголовке HTML?

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
...