2010/01/11

[php]PHP5でxmlをパースす方法について

カフェ関連サイトのシステム開発日記のPHP4でXMLをパースするによるとPHP5では、simplexml関数を使えば簡単にxmlをパースできちゃうみたいです。

というわけで、simplexml関数についてちょっと調べてみることにしました。

ただ説明をするだけだとわけがわからないので、プログラムを作ってみました。
題材としてYahoo画像検索を扱っています。
(Yahoo画像検索結果のフォーマットについてはこちらを参照。)

$yahoo_start_row = 1;
// Yahoo japan seacrh ここから
$url = "http://search.yahooapis.jp/ImageSearchService/V1/imageSearch";
$url = $url."?appid=Yahooのキー";
$url = $url."&query=".$url_string;
$url = $url."&results=30";
$url = $url."&start=".$yahoo_start_row;
//$url = $url."&adult_ok=1";

//リクエストインスタンスの作成
$request = new HTTP_Request();
//問い合わせ先の設定
$request->setURL($url);

//リクエスト開始
$result = $request->sendRequest();
//リクエストが失敗した場合
if(PEAR::isError($result)){
exit();
}

//DOMオブジェクトを作成
$dom = new DOMDocument;

//GETした内容からBODYの部分を取り出し、さらにその内容をxmlとして読み込む
$dom->loadXML($request->getResponseBody());
//読み込みが失敗した時
if(!$dom){
exit();
}

//DOMオブジェクトをSimpleXMLノードとして解析する。
//(こちらの方が解析しやすいみたいです)
$s = simplexml_import_dom($dom);
//domの解析エラーが発生した場合
if(!$s){
exit();
}

//検索結果合計数を取得
//ResultSetタグのtotalResultsReturned属性を取得する
$RecordCount = $s["totalResultsReturned"];

//検索結果の表示を行う
for($i=0;$i<$RecordCount;$i++){
//ResultSetタグの小要素であるResultタグの内容を取得する
$result = $s->Result[$i];
//ここでは例として、Resultタグの小要素であるUrlタグの内容
//(属性ではないので注意)を表示する
print($i.":".$result->Url."<br>");
}

とこんな流れでいけるみたいで、実際に動かしてみたところ確かに、URLが表示されました。

「$dom = new DOMDocument;」から上の部分は、GETリクエストをしているだけなので、これに関しては、前回の記事を参考にしてください。

そこから下が新しい部分で、よーうはいったんDOMオブジェクトを生成し、それを簡単に処理できるようにsimplexml_import_domを使っていますよーということ。

作ってみて思ったのは、なぜ、DOMオブジェクトを経由させてsimplexml_import_dom関数を使わなくちゃいけないのかなと。

simplexml_import_dom($request->getResponseBody())みたいにしてloadXMLメソッドを使わずに直接解析できるようにすればいいじゃんっと思ってしまうのだが。

確かにリファレンスを読むとsimplexml_import_domの引数はDOMオブジェクトだから、いったんloadXMLメソッドを使わなくちゃーいけないっていうのはわかっているんだけど、なんか色々と事情があるんでしょうね。

後、simplexml_import_domで解析した後は、トップがResultSetタグになっていることにも注意したいです。
(つまり、トップノードのxmlのドキュメントバージョンなどが含まれている部分がではないということ)

小タグには、メソッドのようにアクセスを行い、属性は、配列のようにアクセスすればいいみたいです。

この辺は慣れですね。

最後にYahooの画像検索から返ってくる結果のサンプルを掲載します。
(で参考にしたのは、こちらで一部変更を加えています。)

<?xml version="1.0" encoding="UTF-8" ?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:yahoo:jp:srchmi"
xsi:schemaLocation="urn:yahoo:jp:srchmi http://・・・省略・・・"
totalResultsAvailable="437530"
totalResultsReturned="2"
firstResultPosition="1"
>
<Result>
<Title>02 1024</Title>
<Summary>ひまわり大好き</Summary>
<Url>http://www.sunf.jp/wallpaper/02_1024.jpg</Url>
<ClickUrl>http://ClickUrl>
<RefererUrl>http://Url>
<FileSize>202.2kB</FileSize>
<FileFormat>jpeg</FileFormat>
<Height>768</Height>
<Width>1024</Width>
<Thumbnail>
<Url>http://Url>
<Height>105</Height>
<Width>140</Width>
</Thumbnail>
</Result>
<Result>
<Title>pa021228 11</Title>
<Summary />
<Url>http://Url>
<ClickUrl>http://ClickUrl>
<RefererUrl>http://Url>
<FileSize>87.2kB</FileSize>
<FileFormat>jpeg</FileFormat>
<Height>450</Height>
<Width>600</Width>
<Thumbnail>
<Url>http://Url>
<Height>93</Height>
<Width>125</Width>
</Thumbnail>
</Result>
</ResultSet>

もう一つ追加で、

xmlをパースするに当たって参考にしたサイト
Do You PHP?:PHP5を試してみる - SimpleXML関数でRSSしてみる

0 コメント:

コメントを投稿