Я пытаюсь использовать DOMDocument() для загрузки некоторого XML. Я хотел бы сохранить XML с закодированными значениями, но он продолжает декодировать его при вызове saveXML().
См. Следующий код:
$xml_str = "<Name>o'rielly, o-no, s~sdf"sdf' one test</Name>";
$dom = new DOMDocument();
$dom->formatOutput = TRUE;
$dom->preserveWhiteSpace = FALSE;
if($dom->loadXML($xml_str)) {
$saved_XML = $dom->saveXML();
print_r("xml -> {$saved_XML}\n");
}
Оператор print_r вернется:
<?xml version="1.0"?>
<Name>o'rielly, o-no, s~sdf"sdf' one test</Name>
Я пытаюсь вернуть его:
<?xml version="1.0"?>
<Name>o'rielly, o-no, s~sdf"sdf' one test</Name>
Возможно ли это сделать?
Любая помощь будет приветствоваться. Спасибо.
DOM удалит все необходимые символы, но не остальные. Котировки в текстовых узлах не обязательно должны быть экранированы, поэтому DOM не сможет их избежать. При загрузке с парсером XML результат будет равен.
Это зависит от ожидаемого результата. Если вы хотите прочитать специальные символы, просто дайте DOM избежать необходимых символов и проигнорировать остальные. Это упростит чтение XML и уменьшит его. Если вам нужно прочитать объекты, вам придется использовать раздел CDATA или закодировать их.
$xml = <<<'XML'
<Names>
<Name>o'rielly, o-no, s~sdf"sdf' one test</Name>
<Name>o'rielly, o-no, s~sdf"sdf' one test</Name>
<Name><![CDATA[o'rielly, o-no, s~sdf"sdf' one test]]></Name>
<Name>o&#39;rielly, o-no, s~sdf&quot;sdf&#39; one test</Name>
</Names>
XML;
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
echo "Default:\n";
var_dump($xpath->evaluate('string(//Name[1])'));
echo "Entities:\n";
var_dump($xpath->evaluate('string(//Name[2])'));
echo "CDATA Section:\n";
var_dump($xpath->evaluate('string(//Name[3])'));
echo "Encoded Entities:\n";
var_dump($xpath->evaluate('string(//Name[4])'));
Вывод:
Default:
string(35) "o'rielly, o-no, s~sdf"sdf' one test"
Entities:
string(35) "o'rielly, o-no, s~sdf"sdf' one test"
CDATA Section:
string(48) "o'rielly, o-no, s~sdf"sdf' one test"
Encoded Entities:
string(48) "o'rielly, o-no, s~sdf"sdf' one test"
Если вы создадите узлы с надлежащими методами create *, DOM позаботится о кодировании, чтобы вы могли прочитать то же самое значение, которое вы сохранили.
$dom = new DOMDocument();
$dom->formatOutput = TRUE;
$root = $dom->appendChild($dom->createElement('Names'));
$root
->appendChild($dom->createElement('Name'))
->appendChild($dom->createTextNode("O'Reilly"));
$root
->appendChild($dom->createElement('Name'))
->appendChild($dom->createTextNode("O'Reilly"));
$root
->appendChild($dom->createElement('Name'))
->appendChild($dom->createCDataSection("O'Reilly"));
echo $dom->saveXml();
Вывод:
<?xml version="1.0"?>
<Names>
<Name>O'Reilly</Name>
<Name>O&#39;Reilly</Name>
<Name><![CDATA[O'Reilly]]></Name>
</Names>