Как создать правильный XML-файл, используя кодировку UTF-16 с PHP

Я пытаюсь сгенерировать файл XML в кодировке UTF-16 с помощью PHP, но при открытии сгенерированного файла возникает проблема. Я использую DOMDocument для создания файла. С кодировкой UTF-8 нет проблем. При открытии XML-файла с помощью Notepad++ это выглядит так:

<?xml version="1.0" encoding="UTF-16"?>਍㰀伀䈀㸀ഀ
<CLIENT>਍    㰀䈀伀䴀㸀ഀ
  <BO>਍        㰀䄀搀洀䤀渀昀漀㸀ഀ
      <Object>2</Object>਍          㰀嘀攀爀猀椀漀渀㸀㈀㰀⼀嘀攀爀猀椀漀渀㸀ഀ
    </AdmInfo>਍        㰀䈀甀猀椀渀攀猀猀倀愀爀琀渀攀爀猀㸀ഀ
      <row>਍   

         㰀䌀愀爀搀吀礀瀀攀㸀㠀㰀⼀䌀愀爀搀吀礀瀀攀㸀ഀ

... и так далее!!! Может кто-то помочь мне, пожалуйста?

Используя Notepad++, я установил кодировку UTF-8 без спецификации, и файл выглядит так:

 <?xml version="1.0" encoding="UTF-16"?>਍㰀伀䈀㸀ഀ
  <CLIENT>਍    㰀䈀伀䴀㸀ഀ
      <BO>਍        㰀䄀搀洀䤀渀昀漀㸀ഀ
          <Object>2</Object>਍          㰀嘀攀爀猀椀漀渀㸀㈀㰀⼀嘀攀爀猀椀漀渀㸀ഀ
        </AdmInfo>਍        㰀䈀甀猀椀渀攀猀猀倀愀爀琀渀攀爀猀㸀ഀ
          <row>਍            㰀䌀愀爀搀吀礀瀀攀㸀㠀㰀⼀䌀愀爀搀吀礀瀀攀㸀ഀ
            <CardCode>01000001</CardCode>਍          㰀⼀爀漀眀㸀ഀ
        </BusinessPartners>਍      㰀⼀䈀伀㸀ഀ
    </BOM>਍  㰀⼀䌀䰀䤀䔀一吀㸀ഀ

Часть файла PHP как запрос:

    header('Content-Type: text/xml');
                    //header('Content-Transfer-Encoding: binary');
                    $xml = new DOMDocument();
                    $xml->version='1.0';
                    $xml->encoding='UTF-16';
                    $ob_client = $xml->createElement('OB');
                        $client_element = $xml->createElement('CLIENT');
                            $client_bom_element = $xml->createElement('BOM');
                                $client_bo_element = $xml->createElement('BO');
                                    $client_adminfo_element = $xml->createElement('AdmInfo');
                                        $client_adminfo_object_element = $xml->createElement('Object', '2');
                                        $client_adminfo_version_element = $xml->createElement('Version', '2');

                                    $client_BusinessPartners_element = $xml->createElement('BusinessPartners');
                                        $client_BusinessPartners_row_element = $xml->createElement('row');
                                            $client_BusinessPartners_row_cardtype_element = $xml->createElement('CardType', $_XML_CardType);
                                            $client_BusinessPartners_row_cardcode_element = $xml->createElement('CardCode', $_XML_CardCode);

...
$xml->formatOutput = true;                  
                    echo $xml->saveXML();
                    $xml->save('rudy-xml-particulier'.$commandeId.'.xml');

Большое спасибо.

1 ответ

Вы уже сгенерировали XML-файл с UTF-16. Все, что вам нужно сделать, это указать предварительную кодировку, которую вы делаете:

$doc = new DOMDocument();
$doc->encoding='UTF-16';

Таким образом, проблема более вероятна, когда вы добавляете данные, особенно значения элементов. PHP не будет предупреждать вас и не будет препятствовать добавлению байтовых последовательностей, отличных от UTF-8. Вот пример, который провоцирует это даже:

$_XML_CardType = "\xA9"; # non utf-8 byte-sequence (latin-1 copyright symbol)
$xml->createElement('CardType', $_XML_CardType); # returns DOMElement

Затем, когда вы используете

echo $xml->saveXML();

PHP может рассказать вам о проблеме (в зависимости от версии PHP, настроек отчетов об ошибках и базовых библиотек) и (для более новых версий PHP) обрезать строку в том месте, где произошла ошибка. Примерное сообщение об ошибке:

Предупреждение: DOMDocument::saveXML(): преобразование вывода не выполнено из-за ошибки conv, байты 0xA9 0x3C 0x2F 0x69

Поэтому все, что вам нужно сделать, это убедиться, что строковые данные, которые вы используете с createElement значение равно UTF-8. И это уже все, что вам нужно сделать.

Когда вы говорите, что извлекаете данные из базы данных, обратитесь к документации вашей клиентской библиотеки базы данных PHP, чтобы сделать так, чтобы она возвращала строки в кодировке UTF-8. Это должно немедленно решить вашу проблему.

Чтобы убедиться, что вы получите строку в кодировке UTF-8, проверьте ее перед вставкой, например, с помощью регулярного выражения для обнаружения неверной строки UTF-8:

if (!preg_match('//u', $_XML_CardType) {
    throw new Exception("Non utf-8 string deteced.");
}
$xml->createElement('CardType', $_XML_CardType);

Это вызовет исключение вместо вставки затем. Также регистрируйте / отображайте ошибки и следуйте потоку ошибок, чтобы обнаружить дополнительные проблемы.

Другие вопросы по тегам