PHPではSimpleXMLというのものが標準で用意されていて、これを使うと
- XMLファイルまたはXML文字列をオブジェクトに変換
- そのオブジェクトに子要素とか属性を追加したりの操作
- 操作したオブジェクトをXML文字列・ファイルに戻す
みたいな機能が使用可能。XMLが簡単に扱えて便利です。
でも自分自身、「属性値の取得とか要素追加ってどうやるんだっけ?」となることもあって、色々忘れがちなことも多いです。
そこで自分用の意味も込めて基本的なsimpleXMLの使い方(XMLの読み込みとか要素の取得・操作、要素をXMLに戻す方法など...)をまとめました。
このページの目次
XML文字列をSimpleXMLElementに変換する方法
まず初めはXML文字列とかファイルから要素オブジェクトを作成する方法について
SimpleXMLの場合だと SimpleXMLElement というクラスがXMLの要素をオブジェクトとして操作するのに使われます。その基本の作り方は次の通り
まずここでは次のようなXML(文字列)を解析したいとしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?xml version="1.0" encoding="UTF-8"?> <cookies> <cookie> <name>Chocolate biscuit</name> <origin>United Kingdom</origin> </cookie> <cookie> <name>Macaron</name> <origin>France</origin> </cookie> <cookie> <name>Oreo</name> <origin>United States</origin> </cookie> </cookies> |
要素については適当に定義しただけなのであまり気にしないでください。
それでこのXMLを SimpleXMLElement に変換するには次のコードを書けばOK
1 2 3 4 5 6 7 8 9 10 11 |
/** XMLを文字列として定義 */ $xmlstr =<<<EOM <?xml version="1.0" encoding="UTF-8"?> <cookies> <cookie> ‥‥‥(略)‥‥‥‥ </cookies> EOM; $cookies = new SimpleXMLElement($xmlstr); print_r($cookies); |
今回は $xmlstr にヒアドキュメントでXMLを代入しています。
そしてあとは newSimpleXMLElement( $xmlstr ); でインスタンス化するだけで操作可能なXMLオブジェクトになります。変換するだけならとても簡単ですね。
ちなみに上コードで要素を print_r で出力してみると次のような感じで表示されます。
1 2 3 4 5 6 7 8 9 10 |
SimpleXMLElement Object ( [cookie] => Array ( [0] => SimpleXMLElement Object ( [name] => Chocolate biscuit [origin] => United Kingdom ) ...以下略 |
基本的には配列( Array )と SimpleXMLElement の集まりです。
ちなみに文字列として読み込むなら simplexml_load_string という関数も使用可能。例えば上コードをその関数で書き換えるなら次コードの通りです。
1 2 3 |
/** XML文字列から読み込み */ $cookies = simplexml_load_string( $xmlstr ); print_r($cookies); |
この関数はXML文字列を渡して、返り値は SimpleXMLElement オブジェクトを返します。ただ文字列を渡すだけでいいので、わざわざインスタンス化するよりこっちの方が使いやすいですね。
そしてさらにXMLファイルから読み込むなら simplexml_load_file という関数も使用可。例えば cookies.xml というファイルを読み込みしているのが次のコード
1 2 3 |
/** カレントディレクトリから読み込み */ $cookies = simplexml_load_file( 'cookies.xml' ); print_r($cookies); |
返り値は当然SimpleXMLElementオブジェクト(つまり要素)が返ってきます。
以上がSimpleXMLでXMLを解析する基本的な方法
そして次で紹介するように解析した要素はその子要素とか属性にアクセスできます。
SimpleXMLElementの要素・属性を取得するには
オブジェクト可したXMLの子要素とか要素の値、属性値を取得する方法は次の通り
子要素にアクセスする方法
ある要素の下にある子要素は SimpleXMLElement の配列として扱われます。なので n 番目の子要素にアクセスするなら 親要素->子要素[ n - 1 ] のように書けばその子要素にアクセス可能
例えば先ほどの例で1番目(最初)の子要素にアクセスするなら次のコードを書けばOKです。
1 2 |
/** 1番目のcookie要素を取得 */ $cookie = $cookies->cookie[0]; |
$cookies->cookie[0] と書けば「cookie要素のインデックス0番目にアクセスする」という処理になります。
もちろん子要素からさらに孫要素へのアクセスも可能(次コード参照)
1 2 |
/** name要素を取得 */ $name = $cookies->cookie[0]->name[0]; |
何階層下の孫要素でもアクセスの仕方は全く変わりません。
ある要素の属性にアクセスする方法
属性にアクセスする場合は要素の連想配列の添え字に属性名を渡すことでアクセス可能
例えばある要素の id 属性にアクセスしたいなら次のようなコードになるってことです。
1 2 3 4 5 6 7 8 9 10 11 12 |
/** XMLを文字列として定義 */ $xmlstr = <<<EOM <?xml version="1.0" encoding="UTF-8"?> <cookies> <cookie id="oreo"><name>Oreo</name></cookie> </cookies> EOM; $cookies = new SimpleXMLElement( $xmlstr ); $cookie_0 = $cookies->cookie[0]; /** 最初のcookie要素のid属性にアクセス */ $id = cookie['id']; |
上コードみたいに属性名を $cookie_0['id'] として添え字に渡せば属性が取得できます。
ちなみに返ってくるオブジェクトは属性値ではないことに少し注意。次に紹介しますが、値として取得するなら文字列に変換する必要があります。
要素・属性の中身(値)を取得する方法
要素とか属性の値を取得するにはそれを string にキャストすればOKです。
例えば次は先ほどの例でname要素の中身を表示するコード例
1 2 3 |
$cookies = new SimpleXMLElement( $xmlstr ); $cookie_0 = $cookies->cookie[0]; print_r( (string)$cookie_0->name ); |
(string)$cookie_0->name のようにキャストしないとダメです。
なぜなら要素とか属性は常に SimpleXMLElement のオブジェクトとして返されるため。値を取得する場合は必ずキャストしないといけません。
SimpleXMLElementに要素・属性を追加するには
要素とか属性の値は変更したり追加することもできます。その基本的なやり方をコード例を使ってまとめると次の通り
子要素を追加する方法
ある要素に子要素を追加する場合は SimpelXMLElement::addChild メソッドを使います。
追加する子要素名を $name 、要素値を $value 、名前空間を $namespace とすると、
1 |
SimpleXMLElement::addChild($name [, $value, $namespace] ) |
このような引数をとります。ちなみに引数で必須なのは $name だけでそれ以外は任意(オプショナル)。
あとこのメソッドの返り値は新しく追加されたSimpleXMLElementのオブジェクトになります。
例えばこのメソッドを使って子要素を追加するコード例は次の通り
1 2 3 4 5 6 7 8 9 10 |
/** cookies要素だけのXMLを定義 */ $xmlstr =<<<EOM <?xml version="1.0" encoding="UTF-8"?> <cookies></cookies> EOM; $cookies = new SimpleXMLElement($xmlstr); $cookie = $cookies->addChild('cookie'); $cookie->addChild('name', 'oreo'); $cookie->addChild('origin', 'United States'); |
単純に要素だけを追加するなら addChild('cookie') みたいに要素名だけ、要素の中身も含めて追加したいなら addChild('name', 'oreo') みたいに2つ引数を渡して使います。
名前空間(3つ目の引数)まで渡して使うことはあまりないかもしれません。
属性値を追加する方法
ある要素に属性を追加するときは SimpelXMLElement::addAttribute メソッドを使います。
渡す引数は追加する属性名を $name 、属性の値 $value 、名前空間 $namespace とすると、
1 |
SimpleXMLElement::addAttribute($name [, $value, $namespace] ) |
みたいに使います。先ほどのaddChildメソッドと全く同じですね。
例えばこれを使って要素にid属性を追加しているのが次のコード例
1 2 3 4 5 6 7 8 9 10 11 |
/** XMLを文字列として定義 */ $xmlstr =<<<EOM <?xml version="1.0" encoding="UTF-8"?> <cookies> <cookie><name>Oreo</name></cookie> </cookies> EOM; $cookies = new SimpleXMLElement($xmlstr); $cookie_0 = $cookies->cookie; $cookie_0->addAttribute('id', 'oreo'); |
上コーダだと $cookie_0->addAttribute('id', 'oreo') の部分が属性追加しているコードです。属性の場合だと値ごと追加する場合が多いと思います。
あとちなみにaddAttributeメソッドを使わなくても属性追加は可能です。
例えば上コードをこのメソッドなしで書き換えると次の通り
1 2 3 |
$cookies = new SimpleXMLElement($xmlstr); $cookie_0 = $cookies->cookie; $cookie_0['id'] = 'oreo'; |
単純に $cookie_0['id'] = 'oreo'; みたいに添え字形式で値を代入しても特に問題ありません。
SimpleXMLElementオブジェクをXMLに再変換する方法
最後に操作した要素オブジェクトを再びXMLに戻す方法を紹介
これにはsaveXMLメソッドを使えば簡単にできます。
例えば次が要素とか属性を書き換えた後にXMLとして再出力しているコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/** XMLを文字列として定義 */ $xmlstr =<<<EOM <?xml version="1.0" encoding="UTF-8"?> <cookies> <cookie id="oreo"> <name>Oreo</name> </cookie> </cookies> EOM; /** 要素オブジェクトを書き換え */ $cookies = new SimpleXMLElement($xmlstr); $cookies->cookie[0]->name = 'Macaron'; $cookies->cookie[0]['id'] = 'macaron'; /** XML文字列に変換して出力 */ $xmlstr = $cookies->saveXML(); echo $xmlstr; |
上コードだと $cookies->saveXML() みたいに要素オブジェクトに対して呼び出すだけです。
ちなみにこのコードで再生成されたXMLは次の通り
1 2 3 4 5 6 |
<?xml version="1.0" encoding="UTF-8"?> <cookies> <cookie id="macaron"> <name>Macaron</name> </cookie> </cookies> |
ちゃんと要素の中身と属性値が書き換わっているのが確認できます。
ちなみに saveXML の第一引数には次のように保存先のファイル名も渡せます。
1 2 |
/** 外部のXMLファイルに保存 */ $cookies->saveXML( 'cookies.xml' ); |
もしその場出力でなく、外部に保存したい場合はこちらの方法を使うのがベストです。
ここまでのまとめ
ここまでのことを簡単に整理します。
まずXMLをSimpleXMLElementのオブジェクトに変換する方法は次の3つ
- オブジェクトを直接作成する
例えば new SimpleXMLElement( $xmlstr ) のようにして作成
- simplexml_load_string関数から作成
この関数に simplexml_load_string( $xmlstr ) のように文字列を渡しても作成可
- simplexml_load_file関数から作成
この関数に simplexml_load_file( $filename) みたいにファイル名を渡してもOK
直接SimpleXMLElementのオブジェクトを作成することは少ないので、下2つの関数を使うことがどちらかと言えば多いです。
そして次に紹介した要素・属性にアクセスする方法をまとめると次の通り
- 子要素にアクセス
アロー演算子でアクセス。例えば $cookies->cookie[0] とするとcookies要素の中にある0番目のcookie要素が取得可
- 属性にアクセス
要素の添え字に属性名を渡してアクセス。例えば $cookie[ 'id' ] と書けばid属性にアクセスできる。ただし「値ではない」ことに注意
- 要素や属性の値を取得
文字列( string )にキャストすればOK。例えば $cookies->cookie[0]['id'] とするとid属性の値が文字列として取得できる
要素・属性、あとその中身を取得する方法についてはこんな感じです。
さらに要素や属性を追加する方法については次の通り
- 要素を追加する
addChildメソッドを使う。例えば $cookies->addChild('cookie'); とすればcookie要素が末尾に追加される。第二引数まで渡せば要素値も含めて追加可
- 属性を追加する
addAttributeメソッドを使う。例えば $cookies->cookie->addAttribute( 'id', 'oreo' ) を実行すると "oreo" という値を持つIDを追加できる
属性の追加についてはメソッドなしでもできるので無理して使う必要はないかもしれません。
そして最後に要素をXMLに再変換・出力する方法をまとめると次の通り
- XML文字列に変換
要素オブジェクトに対して $cookies->saveXML(); とすれば文字列で返してくれる
- XMLファイルに出力
要素オブジェクトに対して $cookies->saveXML( $file_name ); のようにファイルパスを渡せばそのファイルに出力してくれる
・・・ここまでの内容を簡単にまとめるとこんな感じです。
僕自身あまり SimpleXML の扱いに慣れていないので、一通り使い方をまとめてみました。基本的な使い方さえ覚えてしまえばXMLの扱いが楽になりそうです。
以上 SimleXML の基本的な使い方についてでした。