Создать или вставить XML в CDATA
Я что-то тестировал, но не могу заставить его работать, вот проблема:
У меня есть xml:
<?xml version="1.0" encoding="UTF-8"?>
<history>
<name>
<age/>
</name>
</history>
Я хотел бы вставить CDATA в этот XML, и содержимое CDATA также является частью XML, что-то вроде этого:
<?xml version="1.0" encoding="UTF-8"?>
<history>
<![CDATA[
<name>
<age/>
</name>
]]>
</history>
Я использую DOMDocument для создания XML:
header('Content-Type: text/xml');
$xml = new DOMDocument("1.0","UTF-8");
$base = $xml->appendChild($xml->createElement('history'));
$name = $base->appendChild($xml->createElement('name'));
$age = $name->appendChild($xml->createElement('age'));
$test = $xml->saveXML();
$xml->getElementsByTagName('history')->item(0)->appendChild($xml->createCDATASection($test));
$xml->formatOutput = true;
echo $xml->saveXML();
он генерирует этот XML:
<?xml version="1.0" encoding="UTF-8"?>
<history>
<name>
<age/>
</name>
<![CDATA[<?xml version="1.0" encoding="UTF-8"?><history><name><age/></name></history>]]>
</history>
Проблемы, с которыми я сталкиваюсь в данный момент:
- То, как я смотрю на работу CDATA, похоже, что мне нужно заполнить весь "внутренний xml", прежде чем я смогу вырезать этот "внутренний xml", а затем создать раздел cdata и вставить его в раздел cdata
- Я использую временное решение, которое является str_replace, но я хотел бы максимально использовать функцию domdocument createCData.
1 ответ
Вы на правильном пути. Разделы CDATA - это текст для внешнего документа, фрагмент xml внутри CDATA - это собственный документ или фрагмент.
$xml = new DOMDocument("1.0","UTF-8");
$xml->appendChild($historyNode = $xml->createElement('history'));
$innerXml = new DOMDocument("1.0","UTF-8");
$innerXml->appendChild($nameNode = $innerXml->createElement('name'));
$nameNode->appendChild($ageNode = $innerXml->createElement('age'));
$fragment = $innerXml->saveXml($innerXml->documentElement);
$historyNode->appendChild($xml->createCDATASection($fragment));
$xml->formatOutput = true;
echo $xml->saveXML();
Выход:
<?xml version="1.0" encoding="UTF-8"?>
<history><![CDATA[<name><age/></name>]]></history>
Это будет работать только в том случае, если фрагмент имеет единственный корневой узел (это действительный документ XML). Если на верхнем уровне есть несколько узлов, вам понадобится фиктивный узел. Я добавил адрес в следующий пример, чтобы показать разницу:
$xml = new DOMDocument("1.0","UTF-8");
$xml->appendChild($historyNode = $xml->createElement('history'));
$innerXml = new DOMDocument("1.0","UTF-8");
$innerXml->appendChild($fragmentNode = $innerXml->createElement('fragment'));
$fragmentNode->appendChild($nameNode = $innerXml->createElement('name'));
$nameNode->appendChild($ageNode = $innerXml->createElement('age'));
$fragmentNode->appendChild($addressNode = $innerXml->createElement('address'));
$fragment = '';
foreach ($fragmentNode->childNodes as $childNode) {
$fragment .= $innerXml->saveXml($childNode);
}
$historyNode->appendChild($xml->createCDATASection($fragment));
$xml->formatOutput = true;
echo $xml->saveXML();
Выход:
<history><![CDATA[<name><age/></name><address/>]]></history>