【PHP8.x】Dom\EntityReference::nextSiblingプロパティの使い方
nextSiblingプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
nextSiblingプロパティは、DOMツリーにおいて、現在のエンティティ参照ノードの直後に存在する兄弟ノードを保持する読み取り専用のプロパティです。DOMドキュメントは、HTMLやXMLの各要素やテキストなどを「ノード」と呼ばれるオブジェクトで階層的に表現します。この構造の中で「兄弟ノード」とは、同じ「親ノード」を持つノード同士の関係を指します。このプロパティにアクセスすると、現在のエンティティ参照ノードのすぐ隣に続くノードを、Dom\Nodeオブジェクトとして取得できます。もし現在のノードが、親ノードが持つ子ノードリストの末尾に位置しており、次に続く兄弟ノードが存在しない場合には、このプロパティはnullを返します。この特性は、特定のノードから始まって後続の全兄弟ノードを順番に処理していくようなループ構文で、処理の終了を判定する条件として一般的に利用されます。このプロパティは値の取得のみが可能で、ノードの順序を変更することはできません。
構文(syntax)
1<?php 2 3$dom = new DOMDocument(); 4$xml = <<<XML 5<?xml version="1.0" encoding="utf-8"?> 6<!DOCTYPE root [ 7 <!ENTITY my_entity "entity-text"> 8]> 9<root> 10 <child1>First</child1> 11 &my_entity; 12 <child3>Third</child3> 13</root> 14XML; 15 16// LIBXML_NOENT を指定してエンティティ参照をノードとして読み込む 17$dom->loadXML($xml, LIBXML_NOENT); 18 19// root要素の子ノードを走査 20foreach ($dom->documentElement->childNodes as $node) { 21 // ノードがエンティティ参照 (Dom\EntityReference) の場合 22 if ($node instanceof \Dom\EntityReference) { 23 // nextSibling プロパティで、エンティティ参照の直後にある兄弟ノードを取得 24 $next = $node->nextSibling; 25 26 // 取得したノードの要素名を出力 27 // ここでは、前後の改行(DOMText)をスキップした <child3> が取得される 28 if ($next && $next->nodeType === XML_ELEMENT_NODE) { 29 echo $next->nodeName; // "child3" 30 } 31 break; 32 } 33} 34 35?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
Dom\Node|null
このプロパティは、現在のノードの直後に位置する兄弟ノードを返します。兄弟ノードが存在しない場合は、nullが返されます。
サンプルコード
PHP DOM nextSiblingで兄弟ノードを取得する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * Dom\EntityReference の nextSibling プロパティの使用例を示します。 7 * 8 * この関数は、XMLドキュメント内にいくつかのノードを作成し、 9 * エンティティ参照ノード (&) の直後にある兄弟ノードを取得して、 10 * その内容を表示します。 11 */ 12function demonstrateEntityReferenceNextSibling(): void 13{ 14 // 1. DOMDocumentオブジェクトを作成します 15 $dom = new DOMDocument('1.0', 'UTF-8'); 16 $dom->formatOutput = true; // 出力を見やすく整形する 17 18 // 2. ルート要素を作成してドキュメントに追加します 19 $root = $dom->createElement('content'); 20 $dom->appendChild($root); 21 22 // 3. ルート要素に子ノードを追加します 23 // Text -> EntityReference -> Element という順序で追加します 24 $textNode = $dom->createTextNode('This is an ampersand: '); 25 $entityRef = $dom->createEntityReference('amp'); // & を表すエンティティ参照 26 $elementNode = $dom->createElement('tag', 'This is a sibling element.'); 27 28 $root->appendChild($textNode); 29 $root->appendChild($entityRef); // ここが今回の主役となるノードです 30 $root->appendChild($elementNode); 31 32 // 4. エンティティ参照ノード (&) の次の兄弟ノードを取得します 33 // $entityRef は Dom\EntityReference オブジェクトです 34 // nextSibling プロパティは、ツリー構造でこのノードの直後にあるノードを返します 35 $sibling = $entityRef->nextSibling; 36 37 // 5. 結果を出力します 38 echo "ドキュメント構造:\n"; 39 echo $dom->saveXML(); 40 echo "\n----------------------------------------\n"; 41 echo "対象ノード: " . $entityRef->nodeName . " (エンティティ参照)\n"; 42 43 // nextSibling が存在するかチェックします 44 if ($sibling !== null) { 45 // 取得した兄弟ノードの情報を表示します 46 // この例では、<tag>要素が取得されるはずです 47 echo "nextSibling で取得したノード名: " . $sibling->nodeName . "\n"; 48 echo "nextSibling で取得したノードの内容: " . $sibling->textContent . "\n"; 49 } else { 50 echo "次の兄弟ノードはありません。\n"; 51 } 52} 53 54// 関数を実行して結果を表示します 55demonstrateEntityReferenceNextSibling(); 56 57?>
このPHPコードは、XML文書を操作するDom\EntityReferenceクラスのnextSiblingプロパティの使用例を解説するものです。nextSiblingプロパティは、XML文書の階層構造において、あるノードのすぐ隣に続く「次の兄弟ノード」を取得する機能を提供します。このプロパティは引数を取らず、アクセスするだけで値を取得できます。
サンプルコードでは、まず<content>という親要素を作成し、その中に「テキスト」「エンティティ参照 (&)」「<tag>要素」という3種類の子ノードを順番に追加しています。ここで主役となるのは、中央に配置されたエンティティ参照ノードです。このノードのnextSiblingプロパティにアクセスすることで、その直後にある<tag>`要素のオブジェクトを取得しています。
このプロパティの戻り値は、次の兄弟ノードが存在する場合はそのノードオブジェクト (Dom\Node)、存在しない場合(つまり、自身が最後の子ノードである場合)はnullになります。そのため、コードの最後では、取得した値がnullでないことを確認してから、ノード名や内容を出力しています。このようにnextSiblingプロパティを使うことで、特定のノードを基準に、同じ階層にある後続のノードを簡単にたどることができます。
nextSibling プロパティは、対象ノードの直後に兄弟ノードがない場合に null を返します。そのため、取得した値を使用する前には、サンプルコードのように必ず if 文などで null でないことを確認してください。このチェックを怠るとエラーの原因となります。また、返されるノードは要素だけでなく、人間には見えにくい空白や改行だけのテキストノードである可能性もあります。取得したノードが期待する種類のものか意識することが大切です。これはプロパティであり、メソッドではないため () をつけて呼び出さないよう注意しましょう。