【PHP8.x】Dom\XPath::query()メソッドの使い方
queryメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『queryメソッドは、指定されたXPath式を評価し、関連付けられたDOMドキュメントから一致するノードを検索して結果を返すメソッドです。第一引数には、検索条件となるXPath式を文字列で指定します。例えば、//pという式を渡すと、ドキュメント内に存在する全てのp要素を取得できます。第二引数には、検索の起点となるコンテキストノードをオプションで指定することが可能です。この引数を省略した場合、検索はドキュメントのルート要素から開始されます。このメソッドの戻り値は、評価したXPath式の種類によって型が異なります。通常、ノードの集合を返す式の場合は、見つかったノードが格納されたDOMNodeListオブジェクトが返されます。このオブジェクトをループ処理することで、取得した個々のノードにアクセスできます。一方、count()のような集計関数を含む式の場合は数値(float型)が返されるなど、式の評価結果に応じた値が返却されます。式が不正であったり、評価に失敗した場合にはfalseを返します。このメソッドは、XMLやHTMLドキュメントの構造に対して柔軟な問い合わせを行い、必要な情報を効率的に抽出するために使用されます。』
構文(syntax)
1$xpath->query( 2 string $expression, 3 ?DOMNode $contextNode = null, 4 bool $registerNodeNS = true 5): DOMNodeList|false;
引数(parameters)
string $expression, ?Dom\Node $contextNode = null, bool $registerNodeNS = true
- string $expression: XPathクエリ文字列を指定します
- ?Dom\Node $contextNode = null: XPathクエリのコンテキストとなるノードを指定します。省略するとドキュメント全体が対象になります。
- bool $registerNodeNS = true: XPathクエリ内で使用される名前空間を自動的に登録するかどうかを指定します。
戻り値(return)
Dom\NodeList|false
与えられたXPathクエリにマッチするノードのリスト、またはクエリが無効な場合はfalseを返します。
サンプルコード
PHP Dom\XPath::queryでXMLからタイトルを取得する
1<?php 2 3/** 4 * Dom\XPath::query() を使用してXMLデータから書籍のタイトルを検索し表示します。 5 * 6 * この関数は、XML文字列を解析し、XPathクエリを用いて 7 * すべての<book>要素内にある<title>要素を抽出して、その内容を標準出力に出力します。 8 */ 9function demonstrateXPathQuery(): void 10{ 11 // サンプルとなるXMLデータ 12 $xmlString = <<<XML 13<?xml version="1.0" encoding="UTF-8"?> 14<bookshelf> 15 <book category="Fantasy"> 16 <title lang="en">The Lord of the Rings</title> 17 <author>J.R.R. Tolkien</author> 18 </book> 19 <book category="Science Fiction"> 20 <title lang="en">Dune</title> 21 <author>Frank Herbert</author> 22 </book> 23 <book category="Classic"> 24 <title lang="ja">吾輩は猫である</title> 25 <author>夏目漱石</author> 26 </book> 27</bookshelf> 28XML; 29 30 // Dom\Documentオブジェクトを作成し、XMLを読み込みます 31 $dom = new Dom\Document(); 32 $dom->loadXML($xmlString); 33 34 // Dom\DocumentオブジェクトからDom\XPathオブジェクトを生成します 35 $xpath = new Dom\XPath($dom); 36 37 // 検索するためのXPath式を定義します (すべての<title>要素を取得) 38 $expression = '//book/title'; 39 40 // query()メソッドを実行して、XPath式に一致するノードのリストを取得します 41 // 成功した場合は Dom\NodeList オブジェクト、失敗した場合は false が返ります 42 $titles = $xpath->query($expression); 43 44 // 結果が取得できたか確認します 45 if ($titles !== false) { 46 echo "書籍タイトル一覧:" . PHP_EOL; 47 // 取得したノードリストをループ処理します 48 foreach ($titles as $title) { 49 // nodeValueプロパティで要素のテキスト内容を取得して表示します 50 echo "- " . $title->nodeValue . PHP_EOL; 51 } 52 } else { 53 echo "XPathクエリの実行に失敗しました。" . PHP_EOL; 54 } 55} 56 57// 上記の関数を実行します 58demonstrateXPathQuery(); 59
PHPのDom\XPath::query()メソッドは、XMLドキュメントに対してXPath式というルールを用いて、条件に一致する要素や属性などのノードを検索するための機能です。
サンプルコードでは、まずDom\DocumentオブジェクトにXML形式の書籍リストを読み込み、それを対象とするDom\XPathオブジェクトを生成します。次に、$xpath->query('//book/title')という形でメソッドを呼び出しています。
第一引数$expressionには、検索条件を指定するXPath式を文字列で渡します。この例では'//book/title'を指定することで、「文書内のすべての<book>要素の子要素である<title>要素」を検索するように指示しています。第二引数以降はオプションで、検索の開始位置を特定のノードに限定したりできますが、このコードでは省略されているため文書全体が検索対象となります。
このメソッドは、検索が成功すると、見つかったノードのリストであるDom\NodeListオブジェクトを返します。失敗した場合はfalseが返ります。コードでは、戻り値がfalseでないことを確認した上で、foreach文を使ってDom\NodeListから各<title>要素を一つずつ取り出し、nodeValueプロパティで要素内のテキスト(書籍のタイトル)を取得して表示しています。
Dom\XPath::query()メソッドは、引数で指定したXPath式が不正な場合に false を返します。そのため、戻り値のチェックは if ($titles) のような緩い比較ではなく、サンプルコードのように !== false を使った厳密な判定が必須です。もし一致する要素が0件だった場合、空の Dom\NodeList オブジェクトが返るため、false とは区別して扱う必要があります。また、対象のXMLが名前空間(ネームスペース)を使用している場合は、query() を実行する前に registerNamespace() メソッドで接頭辞を登録しないと要素を正しく検索できない点にも注意してください。
PHP XPath queryでXMLから情報抽出する
1<?php 2 3/** 4 * XML文字列からXPathクエリを使って特定の情報を抽出するサンプル関数 5 * 6 * @return void 7 */ 8function findBookTitlesByAuthor(): void 9{ 10 // サンプルとなるXMLデータ 11 $xmlString = <<<XML 12 <books> 13 <book category="WEB"> 14 <title lang="ja">PHPマスターブック</title> 15 <author>鈴木一郎</author> 16 <year>2023</year> 17 <price>3200</price> 18 </book> 19 <book category="PROGRAMMING"> 20 <title lang="ja">アルゴリズム入門</title> 21 <author>佐藤次郎</author> 22 <year>2022</year> 23 <price>2800</price> 24 </book> 25 <book category="WEB"> 26 <title lang="ja">実践PHP</title> 27 <author>鈴木一郎</author> 28 <year>2024</year> 29 <price>3500</price> 30 </book> 31 </books> 32 XML; 33 34 // 1. DOMDocumentオブジェクトを作成し、XMLを読み込む 35 $doc = new DOMDocument(); 36 $doc->loadXML($xmlString); 37 38 // 2. DOMXPathオブジェクトを作成する 39 $xpath = new DOMXPath($doc); 40 41 // 3. 検索条件となるXPathクエリ文字列を定義する 42 // ここでは、著者が「鈴木一郎」である本のタイトルを検索する 43 $expression = "//book[author='鈴木一郎']/title"; 44 45 // 4. query()メソッドを実行してノードリストを取得する 46 // 第1引数にXPathクエリ文字列を指定する 47 $nodeList = $xpath->query($expression); 48 49 // query()は失敗するとfalseを返すため、結果をチェックする 50 if ($nodeList === false) { 51 echo "XPathクエリの実行に失敗しました。\n"; 52 return; 53 } 54 55 // 5. 取得したノードリスト(DOMNodeList)をループして内容を表示する 56 echo "著者「鈴木一郎」の書籍タイトル一覧:\n"; 57 foreach ($nodeList as $node) { 58 // $node->nodeValueプロパティで要素のテキスト内容を取得 59 echo "- " . $node->nodeValue . "\n"; 60 } 61} 62 63// 関数を実行 64findBookTitlesByAuthor();
このPHPサンプルコードは、DOMXPath::queryメソッドを使用してXMLデータから特定の情報を抽出する方法を示しています。queryメソッドは、XML文書に対してXPathという問い合わせ言語(クエリ言語)を実行し、条件に一致する要素や属性などのノードを探し出すための機能です。
コードの流れとして、まずDOMDocumentクラスでXML文字列を解析・読み込みます。次に、そのDOMDocumentオブジェクトを基にDOMXPathオブジェクトを生成します。これがXPathクエリを実行するための準備です。検索条件は$expressionという文字列変数にXPathの構文で定義します。このサンプルでは「著者が『鈴木一郎』であるbook要素の子要素であるtitle要素」を検索する条件を指定しています。
$xpath->query()の第一引数にこのクエリ文字列を渡して実行すると、検索が開始されます。メソッドの戻り値は、検索に成功した場合は見つかったノードの集合であるDOMNodeListオブジェクト、失敗した場合はfalseとなります。そのため、if文でfalseでないことを確認してから結果を処理するのが安全です。返されたDOMNodeListはforeachでループ処理でき、各ノードのnodeValueプロパティを参照することで、要素が持つテキスト内容(ここでは書籍タイトル)を取得できます。
DOMXPath::queryメソッドは、XML文書から指定した条件に合う要素を探すためのものです。このメソッドは処理に失敗するとfalseを返すため、サンプルコードのように戻り値がfalseでないかを必ず確認してください。このチェックを怠ると、後続の処理でエラーが発生する可能性があります。検索条件となるXPathクエリ文字列の構文が間違っていると、期待した結果が得られない、またはfalseが返る原因になります。正常に取得できた場合、結果はDOMNodeListオブジェクトとなり、foreachで各要素を取り出せます。各要素のテキスト内容はnodeValueプロパティで取得します。