PHP htmlentities и сохранение данных в формате xml

Я пытаюсь сохранить некоторые данные в XML-файле, используя следующий скрипт PHP:

<?php $string = '<a href="google.com/maps">Go to google maps</a> and some special characters ë è & ä etc.'; $string = htmlentities($string, ENT_QUOTES, 'UTF-8'); $doc = new DOMDocument('1.0', 'UTF-8'); $doc->preserveWhiteSpace = false; $doc->formatOutput = true; $root = $doc->createElement('top'); $root = $doc->appendChild($root); $title = $doc->createElement('title'); $title = $root->appendChild($title); $id = $doc->createAttribute('id'); $id->value = '1'; $text = $title->appendChild($id); $text = $doc->createTextNode($string); $text = $title->appendChild($text); $doc->save('data.xml'); echo 'data saved!'; ?> 

Я использую htmlentities, чтобы перевести всю строку в html-формат, если я оставлю это, специальные символы не будут переведены в формат html. это результат:

 <?xml version="1.0" encoding="UTF-8"?> <top> <title id="1">&amp;lt;a href=&amp;quot;google.com/maps&amp;quot;&amp;gt;Go to google maps&amp;lt;/a&amp;gt; and some special characters &amp;euml; &amp;egrave; &amp;amp; &amp;auml; etc.</title> </top> и <?xml version="1.0" encoding="UTF-8"?> <top> <title id="1">&amp;lt;a href=&amp;quot;google.com/maps&amp;quot;&amp;gt;Go to google maps&amp;lt;/a&amp;gt; and some special characters &amp;euml; &amp;egrave; &amp;amp; &amp;auml; etc.</title> </top> 

Амперсанд html-тегов получает двойной html-код: &amp;lt; и амперсанд становится: &amp;amp;

Это нормальное поведение? Или как я могу предотвратить это? Похоже на двойное кодирование.

Попробуйте удалить строку:

 $string = htmlentities($string, ENT_QUOTES, 'UTF-8'); 

Так как текст, переданный createTextNode (), все равно экранирован.

Обновление: если вы хотите, чтобы символы utf-8 были экранированы. Вы можете оставить эту строку и попытаться добавить строку $ непосредственно в createElement ().

Например:

 $title = $doc->createElement('title', $string); $title = $root->appendChild($title); 

В документации PHP говорится, что строка $ не будет удалена. Я не пробовал, но он должен работать.

Именно htmlentities превращает & &amp; При работе с данными xml вы не должны использовать htmlentities, так как DOMDocument будет обрабатывать & &amp; ,

Начиная с php 5.3 кодировка по умолчанию – UTF-8, поэтому нет необходимости конвертировать в UTF-8.

Эта строка:

 $string = htmlentities($string, ENT_QUOTES, 'UTF-8'); 

… кодирует строку как HTML.

Эта строка:

 $text = $doc->createTextNode($string); 

… кодирует вашу строку HTML как XML.

Это дает XML-представление строки HTML. Когда XML анализируется, вы получаете HTML обратно.

как я могу предотвратить это?

Если ваша цель – хранить некоторый текст в XML-документе. Удалите строку, которая кодирует ее как HTML.

Похоже на двойное кодирование.

Довольно много. Он кодируется дважды, он просто использует разные (хотя и очень похожие) методы кодирования для каждого из двух проходов.