PHP DOM
以下のXMLを使用してサンプルコードを解説する。
<?xml version="1.0"?>
<library xmlns:lib="http://sample.com/library">
<book isbn="0111222333">
<lib:title>She sells seashells</lib:title>
<author>Emily</author>
<publisher>store</publisher>
</book>
<book isbn="0123456789">
<title>Eight apes ate eight apples</title>
<author>John</author>
<publisher>shop</publisher>
</book>
<book isbn="9876543210">
<title>Strike</title>
<author>Mike</author>
<publisher>shop</publisher>
</book>
<book isbn="1234567890">
<title>Shine</title>
<author>Jack</author>
<publisher>store</publisher>
</book>
</library>
■読込
ファイルパスを指定
<?php
$dom = new DomDocument();
$dom->load('test.xml');
?>
文字列をDOMとして読込
<?php $dom = new DomDocument(); $dom->loadXML($str); ?>
HTMLファイルとして読込
<?php
$dom = new DomDocument();
$dom->loadHTMLFile('test.html');
?>
HTMLとして読込
<?php $dom = new DomDocument(); $dom->loadHTML($str); ?>
各メソッドについて
| ファイルからの読込 | 文字列からの読込 | |
|---|---|---|
| XML | DomDocument::load | DomDocument::loadXML |
| HTML | DomDocument::loadHTMLFile | DomDocument::loadHTML |
■保存
ファイルへの保存
<?php
$dom = new DomDocument();
$dom->load('test.xml');
if($is_xhtml){
$dom->save('test.xml');
}
else{
$dom->saveHTMLFile('test.html');
}
?>
データとして格納
<?php
$dom = new DomDocument();
$dom->load('test.xml');
if($is_xhtml){
$data = $dom->saveXML();
}
else{
$data = $dom->saveHTML();
}
?>
各メソッドについて
| ファイルに保存 | データとして返す | |
|---|---|---|
| XML | DomDocument::save | DomDocument::saveXML |
| HTML | DomDocument::saveHTMLFile | DomDocument::saveHTML |
■DOMにおけるXPath
以下のようにDomXPathオブジェクトを通して、DomDocumentオブジェクトに対するxpathを実行する。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xpath = new DomXPath($dom);
$result = $xpath->query('/library/book/title/text()');
foreach($result as $title){
print($title->data);
}
/*
Eight apes ate eight apples
Strike
Shine
*/
?>
以下のように、名前空間を使うこともできる。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xpath = new DomXPath($dom);
$xpath->registerNamespace('lib', 'http://sample.com/library');
$result = $xpath->query('//lib:title/text()');
foreach($result as $book){
print($book->data);
}
/*
She sells seashells
*/
?>
■XMLドキュメントの操作
以下のようにして、要素を追加することができる。documentElementはドキュメントのルートの要素を示す。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$book = $dom->createElement('book');
$book->setAttribute('isbn', '0123456789');
$title = $dom->createElement('title');
$txt = $dom->createTextNode('PHP');
$title->appendChild($txt);
$book->appendChild($title);
$author = $dom->createElement('author', 'Jane');
$book->appendChild($author);
$publisher = $dom->createElement('publisher', 'amazon');
$book->appendChild($publisher);
$dom->documentElement->appendChild($book);
/*
<?xml version="1.0" encoding="utf-8"?>
<library>
<book isbn="0111222333">
<title>She sells seashells</title>
<author>Emily</author>
<publisher>store</publisher>
</book>
<book isbn="0123456789">
<title>Eight apes ate eight apples</title>
<author>John</author>
<publisher>shop</publisher>
</book>
<book isbn="9876543210">
<title>Strike</title>
<author>Mike</author>
<publisher>shop</publisher>
</book>
<book isbn="1234567890">
<title>Shine</title>
<author>Jack</author>
<publisher>store</publisher>
</book>
<book isbn="0123456789"><title>PHP</title><author>Jane</author><publisher>amazon</publisher></book></library>
*/
?>
各メソッドについて
- DomElement DomDocument::createElement(string $name[, string $value])
- 新しい要素ノードを生成する。第二引数で要素の値を指定することもできる
- DomAttr DomElement::setAttribute(string $name, string $value)
- 新しい属性を追加する
- DomNode DomNode::appendChild(DomNode $node)
- 子要素を追加する
- DomText DomNode::createTextNode(string $content)
- 新しいテキストノードを生成する
個人的にこのあたりはJavaScriptで馴染んでいるので覚えやすい。
■要素の移動
特定の要素の前に移動する場合は、以下のようにDomNode::insertBeforeメソッドを使用する。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xpath = new DomXPath($dom);
$result = $xpath->query('/library/book');
$xpath->item(1)->paentNode->insertBefore($result->item(1), $result->item(0));
print($dom->saveXML());
/*
<?xml version="1.0" encoding="utf-8"?>
<library>
<book isbn="0123456789">
<title>Eight apes ate eight apples</title>
<author>John</author>
<publisher>shop</publisher>
</book>
<book isbn="0111222333">
<title>She sells seashells</title>
<author>Emily</author>
<publisher>store</publisher>
</book>
<book isbn="9876543210">
<title>Strike</title>
<author>Mike</author>
<publisher>shop</publisher>
</book>
<book isbn="1234567890">
<title>Shine</title>
<author>Jack</author>
<publisher>store</publisher>
</book>
</library>
*/
?>
要素の最後尾に移動する場合は、以下のようにDomNode::appendChildメソッドを使用する。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xpath = new DomXPath($dom);
$result = $xpath->query('/library/book');
$result->item(1)->parentNode->appendChild($result->item(0));
print($dom->saveXML());
/*
<?xml version="1.0" encoding="utf-8"?>
<library>
<book isbn="0123456789">
<title>Eight apes ate eight apples</title>
<author>John</author>
<publisher>shop</publisher>
</book>
<book isbn="9876543210">
<title>Strike</title>
<author>Mike</author>
<publisher>shop</publisher>
</book>
<book isbn="1234567890">
<title>Shine</title>
<author>Jack</author>
<publisher>store</publisher>
</book>
<book isbn="0111222333">
<title>She sells seashells</title>
<author>Emily</author>
<publisher>store</publisher>
</book>
</library>
*/
?>
但し、上述のメソッドはノードをコピーしない。従って、複製を挿入したい場合は、DomNode::cloneNodeメソッドを使用し、複製してから挿入しなければならない。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xpath = new DomXPath($dom);
$result = $xpath->query('/library/book');
$elm = $result->item(0)->cloneNode();
$result->item(1)->parentNode->appendChild($elm);
print($dom->saveXML());
/*
<?xml version="1.0" encoding="utf-8"?>
<library>
<book isbn="0111222333">
<title>She sells seashells</title>
<author>Emily</author>
<publisher>store</publisher>
</book>
<book isbn="0123456789">
<title>Eight apes ate eight apples</title>
<author>John</author>
<publisher>shop</publisher>
</book>
<book isbn="9876543210">
<title>Strike</title>
<author>Mike</author>
<publisher>shop</publisher>
</book>
<book isbn="1234567890">
<title>Shine</title>
<author>Jack</author>
<publisher>store</publisher>
</book>
<book isbn="0111222333"/></library>
*/
?>
各メソッドについて
- DomNode DomNode::insertBefore(DomNode $node[, DomNode $refnode])
- 第一引数で指定したノードが、第二引数で指定したノードの前に挿入される。
- DomNode DomNode::appendChild(DomNode $node)
- DomNodeの最後尾に、引数で指定したノードを挿入する。
- DomNode DomNode::cloneNode(bool $recursive=false)
- DomNodeを複製する。引数にtrueを指定すると子ノードまで含めた複製が生成される。デフォルトはfalse。
■要素の削除
要素を削除するには、以下のようにDomNode::removeChildメソッドを使用する。また、属性を削除するには、DomNode::removeAttributeメソッド使用する。さらに、要素内のテキストを削除したい場合は、DomCharacterData::deleteDataメソッドを使用する。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xpath = new DomXPath($dom);
$result = $xpath->query('/library/book');
$result->item(0)->parentNode->removeChild($result->item(0));
$result->item(1)->removeAttribute('isbn');
$result = $xpath->query('/library/book/publisher/text()');
$result->item(0)->deleteData(0, $result->item(0)->length);
print($dom->saveXML());
/*
<?xml version="1.0" encoding="utf-8"?>
<library>
<book>
<title>Eight apes ate eight apples</title>
<author>John</author>
<publisher></publisher>
</book>
<book isbn="9876543210">
<title>Strike</title>
<author>Mike</author>
<publisher>shop</publisher>
</book>
<book isbn="1234567890">
<title>Shine</title>
<author>Jack</author>
<publisher>store</publisher>
</book>
</library>
*/
?>
各メソッドについて
- DomNode DomNode::removeChild(DomNode $node)
- DomNode内から、引数で指定したノードを削除する。
- bool DomElement::removeAttribute(string $name)
- DomNodeの、引数で指定した属性を削除する。
- void DomCharacterData::deleteData(int $offset, int $count)
- DomCharacterDataを対象として、第一引数で指定したオフセット値から、第二引数で指定した文字数分削除する。
■DOMにおける名前空間の扱い方
以下のように、要素や属性に名前空間を指定した記述をした後で、名前空間とそのURIを示す属性を要素に追加することで、名前空間を扱うことができる。
<?php
$dom = new DomDocument();
$node = $dom->createElement('ns1:somenode');
$node->setAttribute('ns2:someattribute', 'somevalue');
$node2 = $dom->createElement('ns3:anothernode');
$node->appendChild($node2);
$node->setAttribute('xmlns:ns1', 'http://sample.org/ns1');
$node->setAttribute('xmlns:ns2', 'http://sample.org/ns2');
$node->setAttribute('xmlns:ns3', 'http://sample.org/ns3');
$dom->appendChild($node);
print($dom->saveXML());
/*
<?xml version="1.0"?>
<ns1:somenode ns2:someattribute="somevalue" xmlns:ns1="http://sample.org/ns1" xmlns:ns2="http://sample.org/ns2" xmlns:ns3="http://sample.org/ns3">
<ns3:anothernode/>
</ns1:somenode>
*/
?>
但し、以下のようにDomNode::createElementNSメソッドや、DomNode::setAttributeNSを使用すると、自ノードと親ノードに名前空間とそのURIを示す属性が自動的に付加される。
<?php
$dom = new DomDocument();
$node = $dom->createElementNS('http://sample.org/ns1', 'ns1:somenode');
$node->setAttributeNS('http://sample.org/ns2', 'ns2:someattribute', 'somevalue');
$node2 = $dom->createElementNS('http://sample.org/ns3', 'ns3:anothernode');
$node3 = $dom->createElementNS('http://sample.org/ns1', 'ns1:someothernode');
$node->appendChild($node2);
$node->appendChild($node3);
$dom->appendChild($node);
print($dom->saveXML());
/*
<?xml version="1.0"?>
<ns1:somenode xmlns:ns1="http://sample.org/ns1" xmlns:ns2="http://sample.org/ns2" xmlns:ns3="http://sample.org/ns3" ns2:someattribute="somevalue">
<ns3:anothernode xmlns:ns3="http://sample.org/ns3"/>
<ns1:someothernode/>
</ns1:somenode>
*/
?>
出力されるXMLは若干違うものの、後者のコードの方が短くシンプルにはなる。
■SimpleXMLとの相互変換
SimpleXMLからDOMへの変換
以下のように、dom_import_simplexml関数を使用してSimpleXMLからDOMへ変換が行える。
<?php
$xml = new SimpleXMLElement('test.xml', null, true);
$node = dom_import_simplexml($xml);
$dom = new DomDocument();
$dom->importNode($node, true);
$dom->appendChild($node);
print($dom->saveXML());
?>
DOMからSimpleXMLへの変換
以下のように、simplexml_import_dom関数を使用してDOMからSimpleXMLへ変換が行える。
<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xml = simplexml_import_dom($dom);
print($xml->asXML());
?>
TrackBack URL :
Comments (0)
コメントはまだありません»
コメントはまだありません。
この投稿へのコメントの RSS フィード。TrackBack URL
コメントする