トップ > Tech > PHP > デフォルト名前空間xmlnsつきのXMLでのXPath

デフォルト名前空間xmlnsつきのXMLでのXPath

下記のような名前空間のないXMLを扱うとき、

<?xml version="1.0" ?> 
<test>
  <a>
    <b>
      <c>Apple</c>
    </b>
    <b>
      <c>Peach</c>
    </b>
  </a>
</test>

PHPでは下記のようにかけばXPathでノードリストの取得が可能だ。

// XML 文字列読込(例)
$strXml = file_get_contents($url);
// DOMDocument 生成
$xmldom = new DOMDocument();
$xmldom->loadXML($strXml);
// DOMXPath 生成
$xpath = new DOMXPath($xmldom);
// XPath クエリ評価($nodes に DOMNodeList が返る)
$nodes = $xpath->query('/a/b/c');
// ノード値の取得(おそらくAppleが表示される)
echo $nodes->item(0)->nodeValue; 

が、下記のようにxmlns属性でデフォルトの名前空間指定がされている場合は、前述の記法では取得できない。

<?xml version="1.0" ?> 
<test xmlns="http://www.tinyjoker.net/fruit">
  <a>
    <b>
      <c>Apple</c>
    </b>
    <b>
      <c>Peach</c>
    </b>
  </a>
</test>

このようなXMLの場合は、DOMXPathを生成したあと、registerNamespaceで名前空間を設定してやり、XPathにもすべてそのプリフィックスを付加してやらねばならない。

$xpath->registerNamespace('x', $xmlns);
$nodes = $xpath->query('/x:a/x:b/x:c'); 

はっきり言って美しくない。なぜデフォルトの名前空間に対していちいちプリフィックスをつけなければならないのか。

が、いまのところ他に方法も見つからないので、これで対応しておく。

// XML 文字列読込(例)
$strXml = file_get_contents($url);
// DOMDocument 生成
$xmldom = new DOMDocument();
$xmldom->loadXML($strXml);
// DOMXPath 生成
$xpath = new DOMXPath($xmldom);
// 名前空間の登録
$xpath->registerNamespace('x', $xmlns);
// XPath クエリ評価($nodes に DOMNodeList が返る)
$nodes = $xpath->query('/x:a/x:b/x:c');
// ノード値の取得(おそらくAppleが表示される)
echo $nodes->item(0)->nodeValue; 
(2010/06/05 18:45:28)
9069
プロフィール

Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。 好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。 詳しくは Web mixi で。

Bookmark and Share