[PHP]XMLの&(アンパサンド)の扱い

PHPのDomdocumentで&を使うとWarningが出て、&以降が削除される。

DOMDocument::createElementでは、以下のように書いてある。

指定した値はすべてそのまま用いますが、エンティティ参照 < と > だけはエスケープします。& は手動でエスケープする必要があることに注意しましょう。 そうしないと、エンティティ参照の開始とみなされてしまいます。また、” はエスケープされません。

つまり、&は、&amp;にするか、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('&', '&amp;', 'hoge&moge  > sage'));
$rootElm->appendChild($elm);

//最初から&amp;
$elm = $dom->createElement('Item','moge&amp;hoge > sage');
$rootElm->appendChild($elm);

//&amp;にhtmlspecahlcharすると、&が&amp;になるので、&amp;amp;になってしまう。
$elm = $dom->createElement('Item',htmlspecialchars('moge&amp;hoge > sage'));
$rootElm->appendChild($elm);

//&amp;をCDATAをくくると、&amp;がそのまま出てしまう。
$elm = $dom->createElement('Item');
$elm->appendChild($dom->createCDATASection('moge&amp;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&amp;hoge > sage</Item>
  <Item><![CDATA[moge&hoge > sage]]></Item>
</Root>

 

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>