PHPのDomdocumentで&を使うとWarningが出て、&以降が削除される。
DOMDocument::createElementでは、以下のように書いてある。
指定した値はすべてそのまま用いますが、エンティティ参照 < と > だけはエスケープします。& は手動でエスケープする必要があることに注意しましょう。 そうしないと、エンティティ参照の開始とみなされてしまいます。また、” はエスケープされません。
つまり、&は、&にするか、CDATAに包むかしないとXMLが壊れてしまう。
<?php
$dom = new DOMDocument('1.0','UTF-8');
$rootElm = $dom->createElement('Root');
$dom->appendChild($rootElm);
$elm = $dom->createElement('Item','moge');
$rootElm->appendChild($elm);
//エラーになる
//$elm = $dom->createElement('Item','hoge&moge > sage');
//$rootElm->appendChild($elm);
$elm = $dom->createElement('Item','moge > sage');
$rootElm->appendChild($elm);
//CDATA
$elm = $dom->createElement('Item');
$elm->appendChild($dom->createCDATASection('hoge&moge > sage'));
$rootElm->appendChild($elm);
//htmlspechailchar
$elm = $dom->createElement('Item', htmlspecialchars('hoge&moge > sage'));
$rootElm->appendChild($elm);
//replace
$elm = $dom->createElement('Item', str_replace('&', '&', 'hoge&moge > sage'));
$rootElm->appendChild($elm);
//最初から&
$elm = $dom->createElement('Item','moge&hoge > sage');
$rootElm->appendChild($elm);
//&にhtmlspecahlcharすると、&が&になるので、&amp;になってしまう。
$elm = $dom->createElement('Item',htmlspecialchars('moge&hoge > sage'));
$rootElm->appendChild($elm);
//&をCDATAをくくると、&がそのまま出てしまう。
$elm = $dom->createElement('Item');
$elm->appendChild($dom->createCDATASection('moge&hoge > sage'));
$rootElm->appendChild($elm);
header("Content-Type: text/xml");
echo $dom->saveXML();
結果:
<?xml version="1.0" encoding="UTF-8"?> <Root> <Item>moge</Item> <Item>moge > sage</Item> <Item><![CDATA[hoge&moge > sage]]></Item> <Item>hoge&moge > sage</Item> <Item>hoge&moge > sage</Item> <Item>moge&hoge > sage</Item> <Item>moge&hoge > sage</Item> <Item><![CDATA[moge&hoge > sage]]></Item> </Root>