Как создать правильный 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);
Это вызовет исключение вместо вставки затем. Также регистрируйте / отображайте ошибки и следуйте потоку ошибок, чтобы обнаружить дополнительные проблемы.