PHP
XML

SimpleXMLの名前空間・CDATAセクション・整形出力

More than 3 years have passed since last update.


基本


名前空間


例($data)

<?xml version="1.0"?>

<root xmlns:qiita="http://www.w3.org/2001/XMLSchema-instance">
<qiita:a>foo</qiita:a>
<b qiita:c="bar" />
</root>


名前空間つき要素


読み出し

$xml = new SimpleXMLElement($data);

var_dump((string)$xml->children('qiita', true)->a); // string(3) "foo"


書き込み

$xml = new SimpleXMLElement($data);

$xml->addChild('d', 'baz', 'qiita');
$data = $xml->asXML(); // <qiita:d>baz</qiita:d> が追加される


名前空間つき属性


読み出し

$xml = new SimpleXMLElement($data);

var_dump((string)$xml->b->attributes('qiita', true)['c']); // string(3) "bar"


書き込み

$xml = new SimpleXMLElement($data);

$xml->addChild('d')->addAttribute('xmlns:qiita:e', 'qux');
$data = $xml->asXML(); // <d qiita:e="qux" /> が追加される


CDATAセクション


例($data)

<?xml version="1.0"?>

<root xmlns:qiita="http://www.w3.org/2001/XMLSchema-instance">
<a><![CDATA[foo<br />bar]]></a>
</root>


読み出し

$xml = new SimpleXMLElement($data, LIBXML_NOCDATA);

var_dump((string)$xml->a); // string(12) "foo<br />bar"


書き込み

出来ません



整形出力

出来ません


継承クラスの実装

素の SimpleXMLElement では実現できなかったものを SimpleXMLElement2 として継承実装してみます。


クラス定義

<?php

class SimpleXMLElement2 extends \SimpleXMLElement {

/**
* CDATAセクションを自身の内部に生成
*
* @param string $data
* @return SimpleXMElement2 $this
*/

public function setCData($data) {
$dom = dom_import_simplexml($this);
$dom->appendChild($dom->ownerDocument->createCDATASection($data));
return $this;
}

/**
* CDATAセクションを新しい要素の中に生成
*
* @param string $name
* @param string $data
* @param string [$namespace]
* @return SimpleXMElement2 新しい要素
*/

public function addChildWithCData($name, $data, $namespace = null) {
$child = $this->addChild($name, null, $namespace);
$dom = dom_import_simplexml($child);
$dom->appendChild($dom->ownerDocument->createCDATASection($data));
return $child;
}

/**
* XMLを整形して出力
*
* @param string [$filename]
* @return mixed ファイル名を省略したときは文字列、指定したときは書き込み結果
*/

public function asPrettyXML($filename = null) {
$dom = dom_import_simplexml($this);
$dom->ownerDocument->formatOutput = true;
$data = $dom->ownerDocument->saveXML(
$dom->ownerDocument !== $dom->parentNode ? $dom : null
);
return $filename !== null ? (bool)file_put_contents($filename, $data) : $data;
}

}



使用例(コード)

$url  = 'http://www.w3.org/2001/XMLSchema-instance';

$data = 'foo<br />bar';
$out = 'php://output';

$xml = new SimpleXMLElement2('<root xmlns:qiita="' . $url .'" />');
$xml->addChild('a')->setCData($data);
$xml->addChildWithCData('b', $data);
$xml->addChild('c', null, $url)->setCData($data);
$d = $xml->addChildWithCData('d', $data, $url);

echo 'FULL(Normal)' . PHP_EOL;
$xml->asXML($out);
echo PHP_EOL;

echo 'FULL(Pretty)' . PHP_EOL;
$xml->asPrettyXML($out);
echo PHP_EOL;

echo 'D(Normal)' . PHP_EOL;
$d->asXML($out);
echo PHP_EOL, PHP_EOL;

echo 'D(Pretty)' . PHP_EOL;
$d->asPrettyXML($out);
echo PHP_EOL;



使用例(実行結果)

FULL(Normal)

<?xml version="1.0"?>
<root xmlns:qiita="http://www.w3.org/2001/XMLSchema-instance"><a><![CDATA[foo<br />bar]]></a><b><![CDATA[foo<br />bar]]></b><qiita:c><![CDATA[foo<br />bar]]></qiita:c><qiita:d><![CDATA[foo<br />bar]]></qiita:d></root>

FULL(Pretty)
<?xml version="1.0"?>
<root xmlns:qiita="http://www.w3.org/2001/XMLSchema-instance">
<a><![CDATA[foo<br />bar]]></a>
<b><![CDATA[foo<br />bar]]></b>
<qiita:c><![CDATA[foo<br />bar]]></qiita:c>
<qiita:d><![CDATA[foo<br />bar]]></qiita:d>
</root>

D(Normal)
<qiita:d><![CDATA[foo<br />bar]]></qiita:d>

D(Pretty)
<qiita:d><![CDATA[foo<br />bar]]></qiita:d>