Когда я пытаюсь писать строки UTF-8 в файл XML с помощью DomDocument, он фактически записывает шестнадцатеричную нотацию строки вместо самой строки.
например:
ירושלים
вместо: ירושלים
любые идеи, как решить проблему?
Хорошо, здесь вы идете:
$dom = new DOMDocument('1.0', 'utf-8'); $dom->appendChild($dom->createElement('root')); $dom->documentElement->appendChild(new DOMText('ירושלים')); echo $dom->saveXml();
будет работать нормально, потому что в этом случае созданный вами документ сохранит кодировку, указанную в качестве второго аргумента:
<?xml version="1.0" encoding="utf-8"?> <root>ירושלים</root>
Однако, как только вы загружаете XML в документ, который не указывает кодировку, вы потеряете все, что вы заявили в конструкторе, а это означает:
$dom = new DOMDocument('1.0', 'utf-8'); $dom->loadXml('<root/>'); // missing prolog $dom->documentElement->appendChild(new DOMText('ירושלים')); echo $dom->saveXml();
не будет иметь кодировку utf-8:
<?xml version="1.0"?> <root>ירושלים</root>
Поэтому, если вы загружаетеXML-код, убедитесь, что он
$dom = new DOMDocument(); $dom->loadXml('<?xml version="1.0" encoding="utf-8"?><root/>'); $dom->documentElement->appendChild(new DOMText('ירושלים')); echo $dom->saveXml();
и он будет работать, как ожидалось.
В качестве альтернативы вы также можете указать кодировку после загрузки документа.
Если вы хотите вывести UTF-8 с DOMDocument, вам нужно указать это. Простой, не так ли? Если вы уже чувствуете запах уловки, вы не слишком далеко, но на первый взгляд это действительно прямолинейно.
Рассмотрим следующий (код с кодировкой UTF-8) код-пример, который выводит шестнадцатеричные объекты:
$dom = new DOMDocument(); $dom->loadXml('<root>ירושלים</root>'); $dom->save('php://output');
Вывод:
<?xml version="1.0"?> <root>ירושלים</root>
Как написано, если вы хотите вывести это как UTF-8, вам нужно указать его, и он прямолинейный:
... $dom->encoding = 'UTF-8'; $dom->save('php://output');
Выход затем в UTF-8 явно :
<?xml version="1.0" encoding="UTF-8"?> <root>ירושלים</root>
Так много для прямой части. Если вас интересуют грязные мелочи, вы можете читать дальше – если нет, пожалуйста, не спрашивайте «почему?». :).
Я просто написал «в UTF-8 явно », потому что также в первом примере вывод кодируется в кодировке UTF-8, XML содержит только шестнадцатеричные сущности, что совершенно справедливо – даже в UTF-8!
Вы уже заметили, что я начинаю с nit-picking здесь, но помните: UTF-8 является кодировкой по умолчанию XML .
И если вы сейчас начнете говорить: «Эй, подождите, если по умолчанию кодировка UTF-8 в любом случае, почему PHP DOMDocument использует объекты в первую очередь?
Ну, правда, это не противоречит нахождению в вопросе. Не всегда .
См. Следующий пример, который использует XML-комментарий вместо значения узла, содержащего буквы Ivrit:
$dom = new DOMDocument(); $dom->loadXml('<root><!-- ירושלים --></root>'); $dom->save('php://output');
Вывод:
<?xml version="1.0"?> <root><!-- ירושלים --></root>
Хорошо, все ясно? Итак, грязный маленький секрет здесь: есть ли у вас эти XML-объекты или нет – для документа это не имеет никакого значения, это просто другая форма написания тех же XML-данных. И вы уже чувствуете приглашение: Давайте попробуем CDATA вместо первого примера:
$dom = new DOMDocument(); $dom->loadXML("<root><![CDATA[ירושלים]]></root>"); $dom->save('php://output');
Вывод:
<?xml version="1.0"?> <root><![CDATA[ירושלים]]></root>
Поскольку это демонстрируется, например, с примером XML-комментариев, здесь нет XML-объектов. В любом случае, они не будут действительными, как в примере с XML-комментариями.
В обзоре можно создать пример, который содержит все это:
$dom = new DOMDocument(); $dom->loadXML("<!-- ירושלים --><root>ירושלים <![CDATA[ירושלים]]></root>"); $dom->save('php://output');
Вывод:
<?xml version="1.0"?> <!-- ירושלים --> <root>ירושלים <![CDATA[ירושלים]]></root>
Уроки выучены:
Совет. Если ваша строка имеет XML-декларацию, которая не соответствует кодировке строк или вы хотите изменить ее, прежде чем загружать строку в DOMDocument, вам необходимо изменить XML-декларацию и / или перекодировать строку. Это было рассмотрено в ответе на вопрос PHP XMLReader, получить версию и кодировку , показывая, как
XMLRecoder
классXMLRecoder
.
Надеюсь, это все.
[1] Вероятно, если вы загружаетесь из HTTP-запроса и предоставляете контекст потока и помещаете кодировку символов через метаданные, – но сначала это нужно проверить, я не знаю. То, что спецификация не работает, является некоторым признаком того, что все это не работает.
Очевидно, передача документаElement как $ node для saveXML работает вокруг этого, хотя я не могу сказать, что понимаю почему.
например
$dom->saveXML($dom->documentElement);
скорее, чем:
$dom->saveXML();
Источник: http://www.php.net/manual/en/domdocument.savexml.php#88525
Когда я создал DomDocument для записи, я добавил следующие параметры:
dom = new DOMDocument('1.0','utf-8');
эти параметры заставляли строку UTF-8 записываться как есть.
$doc = new DOMDocument(); $doc->loadHTML('<?xml encoding="UTF-8">' . $html); // dirty fix foreach ($doc->childNodes as $item) if ($item->nodeType == XML_PI_NODE) $doc->removeChild($item); // remove hack $doc->encoding = 'UTF-8'; // insert proper
К точному ответу:
Когда ваша функция начнется, сразу после получения содержимого сделайте следующее:
$content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8');
Затем запустите новый документ и т. Д. Проверьте это как пример:
if ( empty( $content ) ) { return false; } $doc = new DOMDocument('1.0', 'utf-8'); libxml_use_internal_errors(true); $doc->LoadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
Затем сделайте все, что вы намеревались сделать с вашим кодом.