@blog.justoneplanet.info

日々勉強

PHP SOAP and REST at Web Service(ウェブサービスでのSOAPとREST)

■SOAP

自サーバにない(所有していない)プログラムのメソッドを呼び出す、リモートプロシージャコール(遠隔呼び出し)のためのプロトコル。相手側がアクセス可能にしているメソッドならばアクセスが可能である。但し、PHPでSOAPを使用するには、インストール時に–enable-soapされていなければならない。

ウェブサービスへのアクセス

以下のようにするとGoogle検索のウェブサービスを利用することができる。

<?php
try {
    $client = new SoapClient('http://api.google.com/GoogleSearch.wsdl');
    $results = $client->doGoogleSearch($key, $query, 0, 10, false, '', false, '', '', '');
    foreach($results->resultElements as $result){
        print('<a href=">' . htmlentities($result->URL, ENT_QUOTES) . '">');
        print(htmlentities($result->title, ENT_COMPAT));
        print('</a>');
    }
}
catch(SoapFault $e){
    $e->getMessage();
}
?>
SoapClientについて
  • Googleに提供されたWSDLファイルに基づきSOAPクライアントを生成する
  • SoapClientは失敗すると例外をスローする
WSDLについて
  • WSDLファイルとは、「提供されている場所」や「メッセージの形式」「プロトコル」「メソッド」など、サービスの具体的内容が記述されている
  • WSDLファイルを使用しない場合は、SoapClientの第一引数にnullを、第二引数でウェブサービスのエントリーポイントのURIを指定しなければならない

デバッグ

SOAPクライアントは、SOAPサーバに送受信したメッセージを用いてデバッグするために特別なメソッドを備えている。但し、使用するためにはSoapClientの第二引数でtraceを1に設定しなければならない。以下のようにすると、生の通信を見ることができる。

<?php
$cleint = new SoapClient(
    'http://api.google.com/GoogleSearch.wsdl',
    array(
        'trace' => 1
    )
);
$results = $client->doGoogleSearch($key, $query, 0, 10, false, '', false, '', '', '');
print($results->__getLastRequestHeaders());
print($result->__getLastRequest());
/*
POST /search/beta2 HTTP/1.1
Host: api.google.com
Connection: Keep-Alive
User-Agent: PHP SOAP 0.1
Connect-Type: text/xml; charset=utf-8
SOAPAction: "url:GoogleSearchAction"
Content-Length: 900

<?xml version="1.0" encoding="UTF-8"?>
...

*/
?>

SOAPサーバの作り方

以下のように、SOAPサーバの挙動を定義する。

<?php
class MySoapServer {
    public function getMessage(){
        return 'Hello, World!';
    }
    public function addNumbers($num1, $num2){
        return (int)$num1 + (int)$num2;
    }
}
?>

以下のように、定義したクラスを実際にSoapServerとして設定する。

<?php
require_once('MySoapServer.class.php');
$server = new SoapServer(
    null,
    array(
        'uri' => 'http://sample.org/soap/server'
    )
);
$server->setClass('MySoapServer');
$server->handle();
?>

以上のような場合、クライアント側のコードは以下のようになる。

<?php
$client = new SoapClient(
    null,
    array(
        'location' => 'http://sample.org/soap/server/server.php',
        'uri'        => 'http://sample.org/soap/server/',
    )
);
print($client->getMessage());//Hello, World!
print($client->addNumbers(1,8));//9
?>

■REST

RESTはプロトコルではなく、ウェブサービスの設計思想の一つである。個々のリソースはURIにおいて参照することができる。

<?php
$user = 'john';
$pass = 'password';
$tag = htmlentities($_POST['tag'], ENT_QUOTES);
$req = "https://{$user}:{$pass}@api.del.icio.us/v1/posts/all?tag={$tag}";

$bookmarks = new SimpleXMLElement($req, null, true);
foreach($bookmarks as $bookmark){
    print('<a href="' . htmlentities($bookmark['href'], ENT_QUOTES) . '">');
    print(htmlentities($bookmark['description'], ENT_COMPAT));
    print('</a>');
}
?>

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());
?>

PHP SimpleXML

以下のXMLを使用してサンプルコードを解説する。

<?xml version="1.0"?>
<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>
</library>

■XMLドキュメントのパース

  • 対応しているXMLのバージョンは1.0(1.1は非対応)
  • パースに失敗すると警告を発する
  • ドキュメントをパースするときは、SimpleXMLElementオブジェクトを生成する必要がある
<?php
$xml = simplexml_load_file('doc/library.xml');
?>

上述のコードは以下のコードと同じ働きをする。

<?php
$doc = file_get_contents('doc/library.xml');
$xml = simplexml_load_string($doc);
?>

オブジェクト指向型のアプローチ

以下のようにSimpleXMLElementクラスを使って、アブじぇ句と指向型のアプローチを取ることもできる。

<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);
?>

上述のコードは以下のコードと同じ働きをする。

<?php
$doc = file_get_contents('doc/library.xml');
$xml = new SimpleXMLElement($doc);
?>

個人的にはオブジェクト指向型のアプローチの方がコードがスッキリして好きだ。

SimpleXMLElement(string $dat[, int $options[, bool $flag_uri[, string $namespace[, bool $is_prefix]]]])
$dat
XML文字列。URLで指定する場合は、第三引数を「true」にしなければならない
$options
libxmlに渡すパラメータ。用途にもよるが、「null」を渡して使用することが多い
$flag_uri
第一引数がURLの場合は、「true」をセットしなくてはならない

■要素と属性へのアクセス

各要素にアクセスするには「->」を使用し、属性にアクセスするためには配列リテラルを使用する。

<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);
foreach($xml->book as $book){
    print($book['isbn'] . PHP_EOL);
    print($book->title . PHP_EOL);
    print($book->author . PHP_EOL);
    print($book->publisher . PHP_EOL);
}
/*
0111222333
She sells seashells
Emily
store
-----
0123456789
Eight apes ate eight apples
John
shop
-----
9876543210
Strike
Mike
shop
-----
1234567890
Shine
Jack
store
-----
*/
?>

但し、上述のコードには「子要素や属性の名前を知っていなければならない」という欠点がある。従って、以下のコードのように、要素名や属性名を取得するメソッドを使う方が良い。

<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);
foreach($xml->children() as $child){
    print($child->getName() . PHP_EOL);
    foreach($child->attributes() as $attr){
        print("\t" . $attr->getName() . ': ' . $attr . PHP_EOL);
    }
    foreach($child->children() as $sub){
        print("\t" . $sub->getName() . ': ' . $sub . PHP_EOL);
    }
    print('-----' . PHP_EOL);
}
/*
book
isbn: 0111222333
title: She sells seashells
author: Emily
publisher: store
-----
book
isbn: 0123456789
title: Eight apes ate eight apples
author: John
publisher: shop
-----
book
isbn: 9876543210
title: Strike
author: Mike
publisher: shop
-----
book
isbn: 1234567890
title: Shine
author: Jack
publisher: store
-----
*/
?>

但し、上述のコードでは深さが特定の場合しか探索できない。深さが不定の場合は、再帰関数やRecursiveIteratorIteratorクラスなどを使用する。

一度値を配列に格納する方法

すぐに出力する場合は上述の方法で問題はないが、配列に要素の文字列を格納する場合はSimpleXMLElementオブジェクトから文字列に変換する。

$data = new SimpleXMLElement($url, null, true);
if($data->getName() === 'rss'){//rss
    foreach($data->channel->item as $i){
        $rv[] = array(
            'title' => ((string)$i->title),
            'link'  => ((string)$i->link)
        );
    }
}
elseif($data->getName() === 'feed'){//atom
    foreach($data->entry as $item){
        $rv[] = array(
            'title' => ((string)$item->title),
            'link'  => ((string)$item->link['href'])
        );
    }
}
各メソッドについて
SimpleXMLElement::children()
指定したノードの子ノードを見つける
SimpleXMLElement::attributes()
属性名をキーとして、指定したノードの属性値の配列を返す
SimpleXMLElement::getName()
要素名、属性名を返す

■XPathクエリ

XPathを使用して特定の要素を抜き出したりするには、以下のように「SimpleXMLElement::xpath」を用いる。

<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);
$elm = $xml->xpath('/library/book/title');
foreach($eml as $title){
    print($title . PHP_EOL);
}
/*
She sells seashells
Eight apes ate eight apples
Strike
Shine
*/
/*
array(4) {
  [0]=>
  object(SimpleXMLElement)#2 (1) {
    [0]=>
    string(19) "She sells seashells"
  }
  [1]=>
  object(SimpleXMLElement)#3 (1) {
    [0]=>
    string(27) "Eight apes ate eight apples"
  }
  [2]=>
  object(SimpleXMLElement)#4 (1) {
    [0]=>
    string(6) "Strike"
  }
  [3]=>
  object(SimpleXMLElement)#5 (1) {
    [0]=>
    string(5) "Shine"
  }
}
*/
?>
<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);
$elm = $xml->book[0]->xpath('title');
foreach($elm as $title){
    print($title . PHP_EOL);
}
//She sells seashells
?>

SimpleXMLElement::xpathメソッドのについて

xpathクエリを実行し、結果をSimpleXMLElementオブジェクトとして返す。

■SimpleXMLによるXMLドキュメントの操作

以下のように、PHP5.1.3以降ではSimpleXMLで要素の追加が行えるようになった。

<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);

$book = $xml->addChild('book');
$book->addAttribute('isbn', '0812550706');
$book->addChild('title', 'She sells seashells');
$book->addChild('author', 'John');
$book->addChild('publisher', 'amazon');

header('Content-type: text/xml');
print($xml->asXML());
/*
<?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="0812550706"><title>She sells seashells</title><author>John</author><publisher>amazon</publisher></book></library>
*/
?>

asXMLメソッドはXML文字列を返す。また、引数にファイルパスを指定した場合は、XMLドキュメントとして保存される。但し、既にファイルが存在している場合は、警告なしにファイルが上書きされるので注意が必要である。

要素の削除

SimpleXMLは要素や属性の追加についてのメソッドを持っているが、削除についてのメソッドは存在しない。削除する場合は以下のようにする。

<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);
$xml->book[0] = null;
/*
<?xml version="1.0" encoding="utf-8"?>
<library>
    <book isbn="0111222333"></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>
*/
?>

但し、この方法は要素内を空にするだけであり、book要素の属性も属性値を空にすることしかできない。もしも、完全に削除したい場合は、DOMへエクスポートする必要がある。以下のようにする。

<?php
$xml = new SimpleXMLElement('doc/library.xml', null, true);
unset($xml->book[0]);
/*
<?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>
</library>
*/
?>
各メソッドについて
SimpleXMLElement::addChild
要素を追加する。戻り値はSimpleXMLElementオブジェクトであり、これに対して操作することでルートのXMLを操作することもできる
SimpleXMLElement::addAttribute
属性を追加する

■名前空間

<?xml version="1.0"?>
<library xmlns="http://sample.org/library" xmlns:meta="http://sample.org/book-meta" xmlns:pub="http://sample.org/publisher" xmlns:sample="http://sample.org/sample">
    <book meta:isbn="0345342968">
        <title>Fahrenheit 451</title>
        <author>Ray Bradbury</author>
        <pub:publisher>Del Rey</pub:publisher>
    </book>
</library>
<?php
$xml = new SimpleXMLElement('test.xml', null, true);
$ns = $xml->getDocNamespaces();
foreach($ns as $key => $value){
	print("{$key}: {$value}\n");
}
/*
: http://sample.org/library
meta: http://sample.org/book-meta
pub: http://sample.org/publisher
sample: http://sample.org/sample
*/
?>

<?php
$xml = new SimpleXMLElement('test.xml', null, true);
$ns = $xml->getNamespaces(true);
foreach($ns as $key => $value){
	print("{$key}: {$value}\n");
}
/*
: http://sample.org/library
meta: http://sample.org/book-meta
pub: http://sample.org/publisher
*/
?>

以下のように、引数にfalseを指定するとカレントノードの名前空間を返す。名前空間が指定されていない場合は、空の配列となる。

<?php
$xml = new SimpleXMLElement('test.xml', null, true);
$ns = $xml->getNamespaces(false);
foreach($ns as $key => $value){
	print("{$key}: {$value}\n");
}
/*
: http://sample.org/library
*/
?>

各メソッドについて

SimpleXMLElement::getDocNamespaces
ドキュメントで宣言されている名前空間を返す。引数にはbool値が入り(デフォルトはfalse)trueを指定すると、子ノードで宣言されている名前空間も返す。
SimpleXMLElement::getNamespaces
ドキュメントで使用している名前空間を返す。引数にはbool値が入り(デフォルトはfalse)trueを指定すると、子ノードで使用している名前空間も返す。