【PHP8.x】Dom\Element::getElementsByTagNameNS()メソッドの使い方
getElementsByTagNameNSメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
getElementsByTagNameNSメソッドは、XML文書などのツリー構造を持つデータ(DOM)から、特定の基準に合致する子孫要素を効率的に検索し取得するために実行されるメソッドです。このメソッドは、呼び出し元のDom\Elementオブジェクトを起点として、その要素の子孫全体の中から、指定された名前空間URIとローカル名を持つすべての要素を見つけ出します。
第一引数の $namespace には、検索したい要素が所属する名前空間のURI(Uniform Resource Identifier)を指定します。これは、異なるXML語彙の要素を識別し、衝突を防ぐために使用されるものです。「*」(アスタリスク)を指定した場合は、名前空間を問わずに要素を検索対象とします。
第二引数の $localName には、検索したい要素のローカル名、つまりタグ名から名前空間の接頭辞を除いた部分を指定します。「*」を指定した場合は、ローカル名を問わずに要素を検索します。
このメソッドは、検索条件に合致したすべてのDom\Elementオブジェクトを格納したDom\NodeListオブジェクトを返します。もし該当する要素が一つも見つからなかった場合でも、空のDom\NodeListオブジェクトが返されます。PHPのDOM拡張機能において、名前空間を利用している複雑なXML文書から特定の情報を効率的かつ正確に抽出する際に、非常に有用な機能として活用されます。
構文(syntax)
1<?php 2 3$xmlString = <<<XML 4<?xml version="1.0" encoding="UTF-8"?> 5<bookstore> 6 <book xmlns:b="urn:books-schema"> 7 <b:title>PHP 8 プログラミング</b:title> 8 </book> 9 <magazine xmlns:m="urn:magazines-schema"> 10 <m:title>月刊システム開発</m:title> 11 </magazine> 12</bookstore> 13XML; 14 15$doc = new DOMDocument(); 16$doc->loadXML($xmlString); 17 18// bookstore要素(ルート要素)を取得 19$rootElement = $doc->documentElement; 20 21// bookstore要素の子孫から、名前空間URIが "urn:books-schema" で、 22// ローカル名が "title" の要素を取得します。 23$bookTitles = $rootElement->getElementsByTagNameNS('urn:books-schema', 'title'); 24 25// 取得した要素のテキスト内容を出力します 26echo $bookTitles[0]->nodeValue; // "PHP 8 プログラミング" 27 28?>
引数(parameters)
?string $namespace, string $localName
- ?string $namespace: 要素を検索する名前空間を指定します。
nullの場合は、名前空間を考慮しません。 - string $localName: 検索する要素のローカル名(名前空間プレフィックスを含まない名前)を指定します。
戻り値(return)
DOMNodeList
指定された名前空間とタグ名に一致するすべての要素のコレクションを DOMNodeList オブジェクトとして返します。
サンプルコード
PHP 8: 名前空間付き要素を getElementsByTagNameNS で検索する
1<?php 2 3// XMLデータを用意します。名前空間が含まれている点に注目してください。 4// 'app' という接頭辞が 'http://example.com/myapp' 名前空間に対応しています。 5$xmlString = <<<XML 6<?xml version="1.0" encoding="UTF-8"?> 7<root xmlns:app="http://example.com/myapp" xmlns:util="http://example.com/utility"> 8 <app:item id="itemA1"> 9 <app:name>Application Item One</app:name> 10 <app:description>This is the first item from the 'myapp' application.</app:description> 11 </app:item> 12 <util:data id="dataU1"> 13 <util:value>Utility Data Value</util:value> 14 </util:data> 15 <app:item id="itemA2"> 16 <app:name>Application Item Two</app:name> 17 </app:item> 18</root> 19XML; 20 21// DOMDocumentオブジェクトを作成し、XMLを読み込みます。 22$dom = new DOMDocument(); 23$dom->loadXML($xmlString); 24 25// ドキュメントのルート要素を取得します。 26// PHP 8では、DOMElementクラスはDom\Elementクラスを実質的に利用しています。 27$rootElement = $dom->documentElement; 28 29// 特定の名前空間URIとローカル名を持つ要素を検索します。 30// ここでは「http://example.com/myapp」名前空間の「item」要素を探します。 31$namespaceURI = 'http://example.com/myapp'; 32$localName = 'item'; 33$items = $rootElement->getElementsByTagNameNS($namespaceURI, $localName); 34 35echo "--- XMLデータ内の要素検索 ---" . PHP_EOL; 36echo "検索条件: 名前空間URI='{$namespaceURI}', ローカル名='{$localName}'" . PHP_EOL; 37echo "------------------------------" . PHP_EOL; 38 39// 取得した要素リスト(DOMNodeList)をループして、各要素の情報を表示します。 40if ($items->count() > 0) { 41 echo "見つかった要素数: " . $items->count() . PHP_EOL . PHP_EOL; 42 foreach ($items as $index => $item) { 43 // $item は Dom\Element (または DOMElement) のインスタンスです。 44 echo "要素 #" . ($index + 1) . ":" . PHP_EOL; 45 echo " 完全なタグ名: " . $item->tagName . PHP_EOL; 46 echo " ローカル名: " . $item->localName . PHP_EOL; 47 echo " 名前空間URI: " . $item->namespaceURI . PHP_EOL; 48 echo " ID属性値: " . $item->getAttribute('id') . PHP_EOL; 49 50 // 子要素(例: name)を取得し、そのテキストコンテンツを表示します。 51 // 子要素も同じ名前空間に属していると仮定して再度 getElementsByTagNameNS を使用します。 52 $nameElements = $item->getElementsByTagNameNS($namespaceURI, 'name'); 53 if ($nameElements->count() > 0) { 54 echo " 名前要素テキスト: " . $nameElements->item(0)->textContent . PHP_EOL; 55 } 56 echo PHP_EOL; 57 } 58} else { 59 echo "指定された条件に一致する要素は見つかりませんでした。" . PHP_EOL; 60} 61 62?>
PHP 8のDom\Element::getElementsByTagNameNSメソッドは、XML文書内で特定の「名前空間(namespace)」と「ローカル名(localName)」を持つ要素を検索するために使われます。XMLの名前空間は、異なるアプリケーションが使用する同じタグ名の要素を区別するための仕組みです。
このメソッドは二つの引数を取ります。一つ目の$namespace引数には、検索したい要素の名前空間を示すURIを指定します。二つ目の$localName引数には、タグ名から名前空間の接頭辞を除いた部分(例: <app:item>であればitem)を指定します。メソッドの戻り値はDOMNodeListオブジェクトで、これは検索条件に一致したすべての要素のリストです。
サンプルコードでは、まず名前空間を含むXMLデータを用意し、DOMDocumentクラスで読み込みます。その後、ドキュメントのルート要素からgetElementsByTagNameNSメソッドを呼び出し、http://example.com/myappという名前空間URIとitemというローカル名を持つ要素を探しています。これにより、<app:item>タグに該当するすべての要素が取得されます。取得された要素リストはループで処理され、各要素の完全なタグ名、ローカル名、名前空間URI、ID属性値などの詳細情報が表示されています。このように、名前空間が定義された複雑なXMLデータから必要な情報を正確に抽出する際に、このメソッドは大変役立ちます。
このメソッドは、XML内の特定の「名前空間URI」と「ローカル名」(タグ名から接頭辞を除いた部分)を持つ要素を正確に検索する際に利用します。第一引数には、XMLに定義されている名前空間の完全なURIを正確に指定してください。XMLの接頭辞(例:app:)そのものではありません。もし名前空間を持たない要素を検索したい場合は、第一引数にnullを指定します。検索結果はDOMNodeListというリスト形式で返されるため、複数の要素が見つかる可能性があることを考慮し、count()で要素数を確認し、ループで各要素を処理することが重要です。名前空間を考慮しない一般的なタグ名での検索には、getElementsByTagNameメソッドを使用してください。
PHP DOM 名前空間付き要素検索
1<?php 2 3use Dom\Document; 4use Dom\Element; 5use DOMNodeList; // リファレンス情報が 'DOMNodeList' のため、この型を使用 6 7/** 8 * Dom\Element::getElementsByTagNameNS メソッドの使用例を示します。 9 * このメソッドは、特定の名前空間URIとローカル名を持つ子孫要素を検索します。 10 */ 11function findElementsByTagNameNSExample(): void 12{ 13 // 名前空間を含むXML文字列を準備します。 14 // 'xmlns' はデフォルトの名前空間、'xmlns:custom' は 'custom' プレフィックスに紐付けられた名前空間を定義します。 15 $xmlString = <<<XML 16<?xml version="1.0" encoding="UTF-8"?> 17<catalog xmlns="http://www.example.com/books" xmlns:custom="http://www.example.com/custom-data"> 18 <book id="bk101"> 19 <title>Everyday Italian</title> 20 <author>Giada De Laurentiis</author> 21 <custom:rating>5</custom:rating> 22 </book> 23 <book id="bk102"> 24 <title>Harry Potter</title> 25 <author>J.K. Rowling</author> 26 <custom:rating>4</custom:rating> 27 </book> 28 <!-- この item タグはデフォルト名前空間を継承しています --> 29 <item>Sample Item</item> 30 <!-- この unqualifiedTag は名前空間を明示的に持っていません --> 31 <unqualifiedTag>No Namespace Tag</unqualifiedTag> 32</catalog> 33XML; 34 35 // Dom\Document オブジェクトを作成し、XMLをロードします。 36 // Dom\Document は PHP 8 で導入された新しい DOM 拡張機能のクラスです。 37 $document = new Document(); 38 $document->loadXML($xmlString); 39 40 // ルート要素を取得します。これが Dom\Element インスタンスとなります。 41 /** @var Element $rootElement */ 42 $rootElement = $document->documentElement; 43 44 echo "--- Dom\\Element::getElementsByTagNameNS の使用例 ---\n"; 45 46 // 例1: デフォルト名前空間の 'book' 要素を検索します。 47 // 第一引数に名前空間のURIを指定します。 48 $defaultNamespaceURI = 'http://www.example.com/books'; 49 $localNameBook = 'book'; 50 echo "\nデフォルト名前空間 ('{$defaultNamespaceURI}') の '{$localNameBook}' 要素を検索:\n"; 51 $books = $rootElement->getElementsByTagNameNS($defaultNamespaceURI, $localNameBook); 52 53 if ($books->count() > 0) { 54 foreach ($books as $book) { 55 // 見つかった書籍のタイトルを表示 (title要素もデフォルト名前空間に属します) 56 $titleNode = $book->getElementsByTagNameNS($defaultNamespaceURI, 'title')->item(0); 57 echo " - 書籍のタイトル: " . ($titleNode ? $titleNode->textContent : 'N/A') . "\n"; 58 } 59 } else { 60 echo " - 見つかりませんでした。\n"; 61 } 62 63 // 例2: 'custom' 名前空間の 'rating' 要素を検索します。 64 $customNamespaceURI = 'http://www.example.com/custom-data'; 65 $localNameRating = 'rating'; 66 echo "\nカスタム名前空間 ('{$customNamespaceURI}') の '{$localNameRating}' 要素を検索:\n"; 67 $ratings = $rootElement->getElementsByTagNameNS($customNamespaceURI, $localNameRating); 68 69 if ($ratings->count() > 0) { 70 foreach ($ratings as $rating) { 71 echo " - 評価: " . $rating->textContent . "\n"; 72 } 73 } else { 74 echo " - 見つかりませんでした。\n"; 75 } 76 77 // 例3: 名前空間を明示的に持たない 'unqualifiedTag' 要素を検索します。 78 // 名前空間URIに空文字列 '' を渡すことで、名前空間を持たない要素を検索できます。 79 $noNamespaceURI = ''; 80 $localNameUnqualified = 'unqualifiedTag'; 81 echo "\n名前空間を持たない ('{$noNamespaceURI}') '{$localNameUnqualified}' 要素を検索:\n"; 82 $unqualifiedTags = $rootElement->getElementsByTagNameNS($noNamespaceURI, $localNameUnqualified); 83 if ($unqualifiedTags->count() > 0) { 84 foreach ($unqualifiedTags as $tag) { 85 echo " - 見つかったタグ: " . $tag->textContent . "\n"; 86 } 87 } else { 88 echo " - 見つかりませんでした。\n"; 89 } 90 91 // 補足: Dom\Element::getElementsByTagName の利用例 92 // このメソッドは名前空間に関わらず、ローカル名が一致するすべての要素を検索します。 93 echo "\n--- Dom\\Element::getElementsByTagName の使用例 (補足) ---\n"; 94 echo "名前空間に関わらず、'title' 要素を検索:\n"; 95 $allTitles = $rootElement->getElementsByTagName('title'); 96 foreach ($allTitles as $title) { 97 echo " - 見つかったタイトル: " . $title->textContent . "\n"; 98 } 99} 100 101// 関数を実行します。 102findElementsByTagNameNSExample();
Dom\Element::getElementsByTagNameNSは、PHPでXMLドキュメントを扱う際に、特定の名前空間URIとタグ名(ローカル名)を持つ要素を検索するために使用するメソッドです。第一引数には検索したい名前空間のURIを文字列で指定し、名前空間を持たない要素を探す場合は空文字列を指定します。第二引数には、プレフィックスを含まないタグ名(ローカル名)を文字列で指定します。このメソッドは、条件に合致するすべての要素をDOMNodeListというオブジェクトとして返します。
サンプルコードでは、名前空間を含むXMLデータを読み込み、その中の要素を検索する具体例を示しています。デフォルトの名前空間に属する「book」要素、カスタム名前空間に属する「rating」要素をそれぞれ検索し、内容を表示しています。また、名前空間を持たない「unqualifiedTag」要素を検索する際には、名前空間の引数に空文字列を渡しています。このメソッドを使用することで、XMLドキュメント内で名前空間によって区別された要素を正確に特定し、操作することが可能になります。名前空間を考慮せずタグ名のみで要素を検索したい場合は、getElementsByTagNameメソッドを利用できます。この機能は、複雑なXML構造から特定の情報を抽出する際に非常に役立ちます。
このメソッドは、指定された名前空間URIとローカル名が完全に一致する要素のみを検索します。XML内の名前空間定義とそのURIが正しいか、特に注意が必要です。デフォルト名前空間の要素を検索する際は、そのURIを第一引数に指定します。また、名前空間を持たない要素を検索する場合は、第一引数に空文字列 '' を渡す必要があります。メソッドは常にDOMNodeListを返しますので、要素が見つからない場合でもnullではなく、count()が0になることを確認してください。名前空間を考慮せず、ローカル名のみで検索したい場合は、getElementsByTagNameメソッドを使用します。これらの違いを理解し、適切に使い分けることが重要です。