XPathを使った要素の取得[XML DOM関数]

メモ:  Category:php

ここでは、XMLからXPathを使って要素を取得する方法を見てみます。

サンプルとしてlivedoorのお天気情報サービス(Livedoor Weather Web Service / LWWS)を使用しています。

http://weather.livedoor.com/forecast/webservice/rest/v1?city=84&day=today

XPathとは、XML文書の中の特定の要素を指し示す記述方法で、基本的な記述はUNIXのファイルシステムに似ています(ロケーションパス)。文書木構造の頂点となるルートノードを「/」であらわし、以下、「/」で区切って要素をたどっていきます。

このロケーションパスは、XPathの主要な部分ですがもっと奥が深いです。

パスを指定して要素を取得

XPathで要素を指定して要素オブジェクトを取得するには、xpath_new_context()とxpath_eval()を使用します。

livedoorのお天気情報サービス(Livedoor Weather Web Service / LWWS)を例にlocation要素を取得して見ます。

<?php

$request = "http://weather.livedoor.com/forecast/webservice/rest/v1?city=84&day=today";

$weatherxml = file_get_contents($request);

$dom = @domxml_open_mem($weatherxml,
        (DOMXML_LOAD_PARSING | 
        DOMXML_LOAD_COMPLETE_ATTRS | 
        DOMXML_LOAD_SUBSTITUTE_ENTITIES | 
        DOMXML_LOAD_DONT_KEEP_BLANKS ));

$xpathcontext = $dom->xpath_new_context();
$xpath = $xpathcontext->xpath_eval("/lwws/location");

var_dump($xpath);

?>

取得結果は、次のようになります。

object(XPathObject)(2) {
  ["type"]=>int(1)
  ["nodeset"]=>array(1) {
    [0]=>object(domelement)(4) {
      ["type"]=>int(1)
      ["tagname"]=>string(8) "location"
      [0]=>int(5)
      [1]=>int(157573576)
    }
  }
}

上記結果からわかるように要素を取得するには、nodeset配列から取得します。

名前空間をつける場合

例えば、xhtml:headのようにタグ名に名前空間をつける場合、PHPでは
あらかじめ指定しておく必要があります。xpath_register_ns()

<?php

$request = "http://weather.livedoor.com/forecast/webservice/rest/v1?city=84&day=today";

$weatherxml = file_get_contents($request);

$dom = @domxml_open_mem($weatherxml,
        (DOMXML_LOAD_PARSING | 
        DOMXML_LOAD_COMPLETE_ATTRS | 
        DOMXML_LOAD_SUBSTITUTE_ENTITIES | 
        DOMXML_LOAD_DONT_KEEP_BLANKS ));

$xpathcontext = $dom->xpath_new_context();
xpath_register_ns($xpathcontext, "wh", "http://wh/");
$xpath = $xpathcontext->xpath_eval("/wh:lwws/wh:location");

var_dump($xpath);

?>

bluenote by BBB