【PHP8.x】Dom\Entity::nextSiblingプロパティの使い方
nextSiblingプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
nextSiblingプロパティは、現在のノードと同じ親を持つ、次に位置する兄弟ノードを保持するプロパティです。DOMツリー構造において、現在のノードの直後にある兄弟ノード(同じ親要素の子ノードとして、現在のノードの次に定義されているノード)への参照を提供します。
このプロパティが保持する値は、次の兄弟ノードが存在する場合、そのノードを表すDom\Nodeオブジェクトです。Dom\Nodeオブジェクトは、要素、テキストノード、コメントノードなど、あらゆる種類のDOMノードの基本となる型です。もし次の兄弟ノードが存在しない場合、つまり現在のノードが親要素の子ノード群の中で最後に位置している場合は、nullが返されます。
このプロパティは、HTMLやXMLといったマークアップ言語のドキュメント構造をプログラムから操作する際に非常に有用です。例えば、特定のノードから始めて、同じレベルに並んだ他のノード群を順番に処理したい場合や、ドキュメントの特定の部分を順方向に走査する際に活用されます。現在のノードを基準にして、隣接する要素への移動を容易にし、複雑なDOMツリーの走査ロジックをシンプルに記述することを可能にします。
構文(syntax)
1<?php 2 3$dom = new DOMDocument(); 4$dom->loadXML('<!DOCTYPE example_doc [<!ENTITY greeting "Hello">]><root/>'); 5 6$doctype = $dom->doctype; 7$entities = $doctype->entities; 8$entity = $entities->item(0); 9 10$nextSiblingNode = $entity->nextSibling; 11 12?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
?Dom\Node
現在のノードの直後に続く兄弟ノードを返します。該当するノードがない場合は null を返します。
サンプルコード
PHP DOM nextSiblingで兄弟ノードを取得する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * DOM要素の nextSibling プロパティの使用方法を示すサンプルクラスです。 7 * nextSibling は、現在のノードの直後にある兄弟ノードを取得します。 8 */ 9final class DomNextSiblingExample 10{ 11 /** 12 * 指定されたHTML内の基準要素から、後続の兄弟ノードをすべて表示します。 13 * 14 * @return void 15 */ 16 public static function run(): void 17 { 18 // 操作対象となるシンプルなHTMLフラグメント 19 // <b>要素の後には、<i>要素と<u>要素が兄弟として並んでいます。 20 $html = '<p><span>Item 1</span><b>Item 2 (基準)</b><i>Item 3</i><u>Item 4</u></p>'; 21 22 // DOMDocumentオブジェクトを生成し、HTMLを読み込みます 23 $dom = new DOMDocument(); 24 // libxmlエラーを抑制し、HTMLをフラグメントとして解析します 25 @$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 26 27 // getElementsByTagNameで基準となる<b>要素を取得します 28 // item(0)は最初に見つかった要素を返します 29 $startNode = $dom->getElementsByTagName('b')->item(0); 30 31 if ($startNode === null) { 32 echo '基準となる<b>要素が見つかりませんでした。' . PHP_EOL; 33 return; 34 } 35 36 echo '基準ノード: <' . $startNode->tagName . '>' . PHP_EOL; 37 echo '---' . PHP_EOL; 38 39 // 基準ノードの nextSibling プロパティを使って次の兄弟ノードを取得します 40 $currentNode = $startNode->nextSibling; 41 42 // 兄弟ノードがなくなるまで (null になるまで) ループを続けます 43 while ($currentNode !== null) { 44 // ノードが要素ノード (DOMElement) かどうかをチェックします 45 // 注意: nextSiblingは要素間の空白や改行などのテキストノードを返すこともあります 46 if ($currentNode instanceof DOMElement) { 47 echo '次の兄弟要素が見つかりました: <' . $currentNode->tagName . '>' . PHP_EOL; 48 } 49 50 // 現在のノードを、さらにその次の兄弟ノードに更新します 51 $currentNode = $currentNode->nextSibling; 52 } 53 } 54} 55 56// サンプルコードを実行します 57DomNextSiblingExample::run();
PHPのDom\Entityクラスが持つnextSiblingプロパティは、DOMツリーにおいて、現在のノードの直後に隣接する兄弟ノードを取得するために使用します。このプロパティに引数はなく、次の兄弟ノードをDom\Nodeオブジェクトとして返します。もし次の兄弟ノードが存在しない場合はnullを返します。
サンプルコードでは、まずHTML文字列から<b>タグを基準ノードとして取得します。そして、$startNode->nextSiblingと記述することで、<b>タグのすぐ後にある兄弟ノード(この場合は<i>タグ)を取得し、変数$currentNodeに代入しています。
次にwhileループを使い、$currentNode = $currentNode->nextSibling;という処理を繰り返すことで、兄弟ノードを順番に辿っていきます。兄弟ノードがなくなるとプロパティはnullを返すため、これがループの終了条件となります。
注意点として、nextSiblingはHTML要素だけでなく、要素間の空白や改行を表す「テキストノード」を取得することもあります。そのため、コード内ではinstanceof DOMElementを使い、取得したノードが意図した要素ノードであるかを確認してから、そのタグ名を表示しています。このようにnextSiblingは、特定の要素から同じ階層にある要素を順に処理したい場合に便利なプロパティです。
nextSiblingプロパティは、HTMLタグなどの「要素ノード」だけでなく、要素間の空白や改行といった目に見えない「テキストノード」も取得する点に注意が必要です。そのため、取得したノードのタグ名を扱う際などは、サンプルコードのようにinstanceof DOMElementを用いて、それが要素ノードであることを確認してから処理を行う必要があります。この確認を怠ると、テキストノードに対して操作しようとしてエラーが発生する原因になります。また、次の兄弟ノードが存在しない場合はnullを返すため、ループ処理ではnullでないことを条件にすることが重要です。