【PHP8.x】Dom\Element::getElementsByTagName()メソッドの使い方
getElementsByTagNameメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
getElementsByTagNameメソッドは、特定のDOM要素を起点として、その配下にある子孫要素の中から指定されたタグ名を持つすべての要素を検索し、取得するメソッドです。このメソッドはDom\Elementオブジェクトから呼び出され、その要素の内部だけが検索対象となります。引数には、検索したい要素のタグ名を文字列で指定します。例えば、'p'を指定すればすべてのp要素が、'div'を指定すればすべてのdiv要素が取得できます。また、ワイルドカードとしてアスタリスク*を指定すると、タグ名に関わらずすべての子孫要素を取得することが可能です。メソッドの返り値は、見つかった要素を文書の出現順に格納したDom\NodeListオブジェクトです。Dom\NodeListは、取得した要素の集合を扱うためのオブジェクトであり、ループ処理などを使って個々の要素にアクセスできます。もし指定したタグ名の要素が一つも見つからなかった場合でも、エラーにはならず、要素数が0の空のDom\NodeListが返されます。文書全体ではなく、特定の範囲内に絞って要素を検索したい場合に非常に便利なメソッドです。
構文(syntax)
1<?php 2 3$html = ' 4<div id="container"> 5 <p>段落1</p> 6 <span>テキスト</span> 7 <div> 8 <p>段落2</p> 9 </div> 10</div> 11'; 12 13$dom = new DOMDocument(); 14$dom->loadHTML($html); 15 16// Dom\Element オブジェクトを取得 17$element = $dom->getElementById('container'); 18 19// Dom\Element::getElementsByTagName(string $qualifiedName): Dom\NodeList 20// $element の子孫の中から、指定したタグ名 ('p') の要素を全て取得する 21$nodeList = $element->getElementsByTagName('p'); 22 23// 取得したリストに含まれる要素の数を出力 24echo $nodeList->length; 25 26?>
引数(parameters)
string $qualifiedName
- string $qualifiedName: 検索したい要素のタグ名を指定する文字列。大文字・小文字は区別されません。
戻り値(return)
Dom\NodeList
指定されたタグ名に一致するすべての Dom\Element オブジェクトの Dom\NodeList を返します。
サンプルコード
PHP: Dom\ElementのgetElementsByTagNameで複数タグを検索する
1<?php 2 3use Dom\Document; 4use Dom\NodeList; 5use Dom\Element; 6 7/** 8 * 指定されたHTML文字列から、複数のタグ名に一致する要素を検索し、その情報を表示します。 9 * Dom\Element::getElementsByTagNameメソッドは単一のタグ名を受け取るため、 10 * 複数の異なるタグを検索するには、それぞれのタグ名に対してこのメソッドを呼び出す必要があります。 11 * 12 * @param string $html HTML文字列 13 * @param array<string> $tagNames 検索したいタグ名の配列(例: ['p', 'span']) 14 */ 15function findMultipleTagsInHtml(string $html, array $tagNames): void 16{ 17 $document = new Document(); 18 // HTMLをパースします。エラーが発生する可能性があるため @ で抑制することが一般的です。 19 // PHP 8ではlibxmlエラーハンドリングが改善されていますが、ここでは簡潔さを優先します。 20 @$document->loadHTML($html); 21 22 echo "--- 検索対象のHTML ---\n"; 23 echo $html . "\n"; 24 echo "----------------------\n\n"; 25 26 // Dom\Element::getElementsByTagName を使用するために、まずDom\Elementインスタンスが必要です。 27 // ここでは、ドキュメントのbody要素を最初の検索対象のElementとします。 28 $bodyElements = $document->getElementsByTagName('body'); 29 30 if ($bodyElements->count() === 0) { 31 echo "HTMLドキュメントにbody要素が見つかりませんでした。\n"; 32 return; 33 } 34 35 /** @var Element $body HTMLドキュメントの最初のbody要素 */ 36 $body = $bodyElements->item(0); 37 38 // 指定された各タグ名についてループし、要素を検索します。 39 foreach ($tagNames as $tagName) { 40 echo "=== タグ名: <{$tagName}> の要素 ===\n"; 41 42 // body要素の子孫から、現在のタグ名を持つすべての要素を検索します。 43 // このメソッドは Dom\NodeList を返します。 44 $elements = $body->getElementsByTagName($tagName); 45 46 if ($elements->count() === 0) { 47 echo " 見つかりませんでした。\n"; 48 continue; 49 } 50 51 // 見つかった各要素について、そのタグ名とテキストコンテンツを表示します。 52 foreach ($elements as $index => $element) { 53 echo " [{$index}] タグ名: {$element->tagName}, コンテンツ: \"{$element->textContent}\"\n"; 54 } 55 echo "\n"; 56 } 57} 58 59// サンプルHTMLデータ 60$sampleHtml = <<<HTML 61<!DOCTYPE html> 62<html> 63<head> 64 <title>サンプルページ</title> 65</head> 66<body> 67 <h1>DOM操作の例</h1> 68 <p>これは最初の段落です。</p> 69 <div> 70 <span class="highlight">ハイライトされたテキスト</span> 71 <p>これは<b>二番目の</b>段落です。</p> 72 <ul> 73 <li>リストアイテム1</li> 74 <li>リストアイテム2</li> 75 </ul> 76 </div> 77 <a href="#">リンク</a> 78</body> 79</html> 80HTML; 81 82// 複数のタグ名を配列で指定し、関数を呼び出します。 83// これにより、それぞれのタグ名に一致する要素が個別に検索・表示されます。 84findMultipleTagsInHtml($sampleHtml, ['p', 'span', 'h1', 'li', 'a']); 85
Dom\Element::getElementsByTagNameは、HTMLドキュメント内の特定の要素(Dom\Elementインスタンス)を起点として、その子孫の中から指定されたタグ名を持つ要素をすべて取得するためのメソッドです。このメソッドは、引数として検索したいタグ名(例: 'p'や'span')を文字列で一つだけ受け取ります。戻り値はDom\NodeListというオブジェクトで、これは見つかった要素の集合を表し、要素が見つからなかった場合は空のリストを返します。Dom\NodeList内の個々の要素には、foreachループやitem()メソッドを使ってDom\Elementとしてアクセスできます。
サンプルコードでは、このメソッドが一度に一つのタグ名しか検索できないという特性を理解し、複数の異なるタグ(例えば'p'、'span'、'h1'など)を見つけるための応用例を示しています。まず、Dom\Documentクラスを使ってHTML文字列を解析し、DOMツリーを構築します。次に、検索の基準となるDom\Elementインスタンスとして、ドキュメントのbody要素を取得しています。これは通常、HTMLコンテンツの大部分が含まれる場所です。その後、検索したい複数のタグ名が配列で与えられているため、その配列をループさせ、各タグ名についてbody要素からgetElementsByTagNameメソッドを繰り返し呼び出しています。これにより、それぞれのタグ名に合致する要素がDom\NodeListとして個別に取得されます。取得したDom\NodeListからは、foreachループを使って個々のDom\Elementにアクセスし、そのtagNameプロパティやtextContentプロパティを読み出して表示しています。このメソッドは、ウェブページから特定の情報を抽出したり、HTML構造を解析したりする際に非常に基本的ながらも重要な役割を果たします。
このサンプルコードは、Dom\Element::getElementsByTagNameメソッドを使って複数のタグに一致する要素を検索する方法を示しています。このメソッドは一度に一つのタグ名しか受け付けないため、複数のタグを検索する場合は、ループ処理で各タグ名に対して個別に呼び出す必要があります。検索は、メソッドを呼び出したDom\Element(例ではbody要素)の子孫要素から行われる点にご注意ください。HTMLのパース時に@でエラーを抑制していますが、実運用ではlibxml関連関数を使ってエラーを適切に処理するべきです。検索結果はDom\NodeListオブジェクトとして返されますので、count()で要素数を、foreachで個々の要素にアクセスし、そのtagNameやtextContentなどを取得して利用します。
PHP Dom\Element: getElementsByTagNameで要素を検索する
1<?php 2 3/** 4 * Dom\Element::getElementsByTagName メソッドの使用例を示す関数です。 5 * 6 * このメソッドは、特定の Dom\Element の子孫要素の中から、 7 * 指定されたタグ名を持つすべての要素を Dom\NodeList として返します。 8 */ 9function demonstrateGetElementsByTagName(): void 10{ 11 // 処理するHTMLコンテンツを定義します。 12 // PHP 8ではDom\Document::loadHTML() でHTML5のタグや形式が原因で 13 // 警告が出ることがあるため、@で抑制することが一般的です。 14 $htmlContent = <<<HTML 15<!DOCTYPE html> 16<html> 17<head> 18 <title>サンプルドキュメント</title> 19</head> 20<body> 21 <h1>DOM操作の基本</h1> 22 <div id="container"> 23 <p>これは最初の段落です。</p> 24 <p class="intro">これは導入の段落です。</p> 25 <ul> 26 <li>リストアイテム1</li> 27 <li>リストアイテム2</li> 28 </ul> 29 <div> 30 <span>内部スパン</span> 31 <p>ネストされた段落です。</p> 32 </div> 33 </div> 34 <p>これはフッターの段落です。</p> 35</body> 36</html> 37HTML; 38 39 // Dom\Document オブジェクトを作成します。 40 $dom = new Dom\Document(); 41 42 // HTML文字列をDOMドキュメントに読み込みます。 43 @$dom->loadHTML($htmlContent); 44 45 // ドキュメントのbody要素を取得します。 46 // Dom\Document::getElementsByTagName は Dom\NodeList を返します。 47 // 通常、bodyタグはHTMLドキュメントに一つだけ存在します。 48 $bodyElements = $dom->getElementsByTagName('body'); 49 50 // body要素が正しく取得できたかを確認します。 51 if ($bodyElements->count() > 0) { 52 // 取得したDom\NodeListから最初の要素(body要素)を取り出します。 53 // この $bodyElement は Dom\Element のインスタンスです。 54 $bodyElement = $bodyElements->item(0); 55 56 echo "--- body要素内の 'p' タグを検索 --- \n"; 57 // Dom\Element::getElementsByTagName メソッドを呼び出します。 58 // $bodyElement の子孫の中から、全ての 'p' タグを持つ要素を取得します。 59 // 戻り値は、マッチした要素を含む Dom\NodeList です。 60 $paragraphsInBody = $bodyElement->getElementsByTagName('p'); 61 62 // 取得した Dom\NodeList をループし、各段落要素のテキストコンテンツを表示します。 63 foreach ($paragraphsInBody as $index => $paragraph) { 64 // $paragraph は Dom\Element のインスタンスです。 65 echo " 段落 " . ($index + 1) . ": " . $paragraph->textContent . "\n"; 66 } 67 68 echo "\n"; 69 70 echo "--- body要素内の 'span' タグを検索 --- \n"; 71 // 同様に、$bodyElement の子孫の中から、全ての 'span' タグを持つ要素を取得します。 72 $spansInBody = $bodyElement->getElementsByTagName('span'); 73 74 // 取得した Dom\NodeList をループし、各スパン要素のテキストコンテンツを表示します。 75 foreach ($spansInBody as $index => $span) { 76 echo " スパン " . ($index + 1) . ": " . $span->textContent . "\n"; 77 } 78 } else { 79 echo "HTMLドキュメントからbody要素が見つかりませんでした。\n"; 80 } 81} 82 83// 上で定義した関数を実行し、Dom\Element::getElementsByTagName の動作を確認します。 84demonstrateGetElementsByTagName();
Dom\Element::getElementsByTagName メソッドは、HTMLやXMLドキュメント内で、特定のHTML要素(Dom\Element)を基点として、その要素の子孫の中から指定されたタグ名を持つすべての要素を検索し、取得するために使用されます。
このメソッドの引数 $qualifiedName には、検索したいHTMLタグの名前を文字列で指定します。例えば、「p」を指定すればすべての段落要素が対象となります。戻り値は Dom\NodeList となり、これは見つかった複数の要素をまとめたリスト形式のオブジェクトです。このリストから、取得した各要素を一つずつ取り出して操作することができます。
サンプルコードでは、まず定義されたHTMLコンテンツをDom\Documentオブジェクトに読み込みます。次に、ドキュメント全体からbody要素を取得し、このbody要素を検索の起点としています。そして、$bodyElement->getElementsByTagName('p') と記述することで、bodyタグ内に存在するすべてのpタグ要素を取得し、そのテキストコンテンツを表示しています。同様に、「span」タグを持つ要素も検索し、表示する例が示されています。このように、特定の要素の内部に限定してタグ検索を行いたい場合に非常に便利で、効率的なDOM操作を可能にします。
Dom\Element::getElementsByTagNameは、このメソッドを呼び出した特定の要素の子孫要素の中から、指定されたタグ名を持つ要素を検索します。ドキュメント全体を検索したい場合は、Dom\Documentインスタンスから呼び出す必要がありますので、検索範囲に注意してください。
このメソッドの戻り値は常にDom\NodeListオブジェクトです。これはマッチした要素のリストであり、直接個々の要素ではありません。リスト内の要素にアクセスする際は、foreachループを使用するか、item()メソッドでインデックスを指定して取得してください。
検索の結果、該当する要素が見つからない場合もDom\NodeListが返されますが、そのcount()は0となります。要素にアクセスする前には、必ずcount()メソッドでリストが空でないことを確認し、存在しない要素へのアクセスによるエラーを防ぐようにしてください。
サンプルコードでDom\Document::loadHTML()に@が付いていますが、これは警告を一時的に抑制するものです。本番環境では、HTMLの構文チェックや適切なエラーハンドリングを検討することをお勧めします。