PHPのXMLパーサー、SimpleXMLElementの使い方

サイト運営

今まで面倒なのでできるだけ避けてきた、XMLファイルを取り扱わなくてはいけなくなりました。

何がなんだかわからないところから、トライアンドエラーでできたソースコードがこんな感じです。

PHP-simpleXML

もちろんこれだけではないのですが、何時間掛かったんだろう・・・。忘れないうちに備忘録として書いていきます。(もう忘れてきています)

SimpleXMLElement

SimpleXMLElementはPHPバージョン5.0.1以上で使えるXML構文解析クラスです。

使い方はシンプルなのですが、ドキュメントも比較的シンプルで本家を読んでも結局トライアンドエラー・・・。

RSSやATOMフィードもXML形式なので読めますが、RSSやATOMは専用ツールがたくさんあるので、そちらを使いましょう。

使い方は、確かに「シンプル」なのです。

$xml = new simpleXMLElement("XMLファイルなど");

これだけでとりあえず構造解析が終わっています。シンプルです。

読み込むデータソースがURLの場合には、

$xml = new simpleXMLElement("XMLファイルのURL", 0, true);

になります。0 はファイル読み込み用のlibxmlに渡るオプションでデフォルトが 0 です。次のオプションがデータソースがURLかどうかを指定しています。

simpleXMLElementのコンストラクタを直接呼ぶ方法だけではなく、

$xml = simplexml_load_file($request_url);

でも読み込みが出来ます。ただし、PHP 5.1.0より前のバージョンでは、php.netによると

Libxml 2 は URI をエスケープしませんので、例えば URI パラメータ ab&c を渡したい場合、simplexml_load_file(rawurlencode(‘http://example.com/?a=’ . urlencode(‘b&c’))) をしてコールする必要があります。

だそうです。また、URLではなく file_get_contents() などで取得したテキストだったりした場合は、simplexml_load_string()関数やsimpleXMLElementコンストラクタで読み込むことでsimpleXMLElementオブジェクトを作ります。

取得して解析を行うのは簡単なのですが、解析された構造を使えるようにするのは、元のXML文書によりますがそんなに単純ではないこともあります。

忘れないうちに、備忘録的にはまった点を書いていきます

simpleXMLElementを使って取得した要素はsimpleXMLElementで得られる

XML文書の構造上、そのようにあるべきなのですが、子要素を得ていっても基本的にはsimpleXMLElementです。

echoにだまされるな

echoして取得した場合、内容の値が一定の条件で表示されてしまいました。(私の使ったPHP 5.3.39では)

<hogehoge name="hello">World!!</hogehoge>

という要素に対してechoをかけると、「World!!」と表示されてしまうのです。echoを使っても良いようなときには大丈夫ですが、式に代入するとおかしくなります。

要素が一つしかないsimpleXMLElementオブジェクトに対してechoすると値が出てしまうようです。作っていく途中で確認・デバッグするときには、print_rかvar_dumpを使いましょう。

[[@attributes]]は直接見れない

次に、print_rやvar_dumpをしたときには要素の属性値(先の例の場合には「name => “hello”」)が[[@attributes]]要素として表示されます。

配列的にアクセスするわけではなく、$xml[[‘name’]]で取得されます。

同じ名前の要素が並んでいる場合は[[順番]]でアクセス

<hogehoge>1番</hogehoge>
<hogehoge>2番</hogehoge>
<hogehoge>3番</hogehoge>

というように同じ書式の要素が並んでいる場合は、$xml[[0]]などのようにアクセスします。こうなることで、foreach入れ子との相性が良くなります。

要素の内容には”->”などでアクセス

要素の内容に対しては、直接アクセスを向けると戻ってきます。XMLが入れ子になっている場合はsimpleXMLElementが返り値になりますが、中身が値の場合には値が返されます。

ただし、一つしかない場合にも配列なので、型キャストが必要です。simpleXMLElement自体を配列に型キャストすることもでき、先頭の要素に属性値が収まっていたような。

次に必要なときに覚えていますように・・・

次にXMLへのアクセスが必要になったときに、また大混乱になる気がします。少しでもこの文章を見て思い出すと良いのですが・・・・。

(間違っている内容が含まれているとおもいます。ご注意ください)

コメント

タイトルとURLをコピーしました