【PHP8.x】DOMEntityReference::parentNodeプロパティの使い方
parentNodeプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『parentNodeプロパティは、現在のエンティティ参照ノード(DOMEntityReference)の親ノードを保持する読み取り専用のプロパティです。DOM(Document Object Model)は、HTMLやXML文書を階層的なツリー構造として表現します。この構造において、文書を構成する各要素やテキストは「ノード」と呼ばれ、互いに親子関係を持っています。parentNodeプロパティは、あるノードがどのノードの直接の子要素であるか、すなわちその「親」にあたるノードが何であるかを示します。例えば、XML文書内で<element>&example;</element>のようにエンティティ参照が使われている場合、&example;を表すエンティティ参照ノードのparentNodeは、それを含んでいる<element>を表す要素ノードになります。このプロパティにアクセスすると、親ノードを表すDOMNodeオブジェクトを取得できます。もし対象のノードがまだ文書に追加されていないなど、親ノードが存在しない状況ではnullが返されます。このプロパティにより、特定のエンティティ参照が文書内のどの部分に属しているかをプログラムで特定し、構造を遡って操作することが可能になります。』
構文(syntax)
1<?php 2 3$xml = <<<XML 4<?xml version="1.0" encoding="UTF-8"?> 5<!DOCTYPE root [ 6 <!ENTITY myEntity "some text"> 7]> 8<root> 9 <element>This contains &myEntity;.</element> 10</root> 11XML; 12 13$doc = new DOMDocument(); 14$doc->substituteEntities = false; 15$doc->loadXML($xml); 16 17$element = $doc->getElementsByTagName('element')->item(0); 18 19foreach ($element->childNodes as $node) { 20 // $node が DOMEntityReference のインスタンスであるかを確認 21 if ($node instanceof DOMEntityReference) { 22 // parentNode プロパティで親ノードを取得 23 $parentNode = $node->parentNode; 24 25 // 親ノードのタグ名を出力 26 echo $parentNode->tagName; // "element" 27 break; 28 } 29}
引数(parameters)
引数なし
引数はありません
戻り値(return)
DOMNode|null
DOMEntityReferenceオブジェクトが属する親ノードを表すDOMNodeオブジェクト、または親ノードが存在しない場合はnullを返します。
サンプルコード
PHP DOM parentNode で親ノードを取得する
1<?php 2 3/** 4 * DOMEntityReferenceのparentNodeプロパティの使用例を示します。 5 * 6 * XMLドキュメント内のエンティティ参照ノードを見つけ出し、 7 * その親ノードの情報を出力することで、parentNodeプロパティの動作を解説します。 8 */ 9function demonstrateEntityReferenceParentNode(): void 10{ 11 // エンティティ参照(&writer;)を含むXML文字列を定義します。 12 // XML内でエンティティを使用するには、DTD(文書型定義)で宣言する必要があります。 13 $xmlString = <<<XML 14<?xml version="1.0" encoding="UTF-8"?> 15<!DOCTYPE note [ 16 <!ENTITY writer "John Doe"> 17]> 18<note> 19 <p>This is a sample note from &writer;.</p> 20</note> 21XML; 22 23 // DOMDocumentオブジェクトをインスタンス化します。 24 $dom = new DOMDocument(); 25 26 // XML文字列を読み込み、DOMツリーを構築します。 27 // エンティティ参照をノードとして保持するため、オプションは指定しません。 28 $dom->loadXML($xmlString); 29 30 // <p> タグを持つ要素を取得します。 31 // getElementsByTagNameはDOMNodeListを返すため、item(0)で最初の要素を取得します。 32 $paragraphElement = $dom->getElementsByTagName('p')->item(0); 33 34 // <p> 要素の子ノードを順番にチェックします。 35 foreach ($paragraphElement->childNodes as $childNode) { 36 // ノードがエンティティ参照(DOMEntityReference)であるかを確認します。 37 if ($childNode instanceof DOMEntityReference) { 38 echo "エンティティ参照ノードが見つかりました: &" . $childNode->nodeName . ";\n"; 39 40 // parentNodeプロパティにアクセスして親ノードを取得します。 41 $parentNode = $childNode->parentNode; 42 43 // 親ノードが存在することを確認し、そのノード名(タグ名)を出力します。 44 if ($parentNode !== null) { 45 echo "このエンティティ参照の親ノードは <" . $parentNode->nodeName . "> です。\n"; 46 } else { 47 echo "このエンティティ参照に親ノードはありません。\n"; 48 } 49 50 // 目的のノードを見つけたので、ループを終了します。 51 break; 52 } 53 } 54} 55 56// 関数を実行して結果を表示します。 57demonstrateEntityReferenceParentNode(); 58 59?>
DOMEntityReferenceクラスのparentNodeプロパティは、XMLドキュメント内のエンティティ参照ノードが、どのノードの子要素であるか、つまり親ノードを取得するためのものです。このプロパティは引数を取らず、親ノードを表すDOMNodeオブジェクトを返します。もし親ノードが存在しない場合はnullを返します。
サンプルコードでは、まずエンティティ参照&writer;を含むXML文字列をDOMDocumentオブジェクトとして読み込んでいます。次に、getElementsByTagNameで取得した<p>要素の子ノードを一つずつ調べ、ノードの種類がDOMEntityReferenceであるものを探します。
対象の&writer;ノードが見つかると、parentNodeプロパティにアクセスしてその親ノードを取得します。このXMLの構造では&writer;は<p>タグの中に記述されているため、親ノードは<p>要素となります。最後に、取得した親ノードのnodeNameプロパティ(この場合は 'p')を出力して、親子関係を確認しています。このようにparentNodeプロパティを使うことで、DOMツリーの階層構造を子から親へと辿ることができます。
parentNodeプロパティは、親ノードが存在しない場合にnullを返すため、利用前には必ずnullチェックが必要です。チェックを怠ると、nullのプロパティにアクセスしようとしてエラーが発生する原因となります。また、サンプルコードのようにエンティティ参照をノードとして扱うには、loadXMLメソッドをオプションなしで実行する必要があります。もしLIBXML_NOENTオプションを指定すると、エンティティはテキストに置き換えられ、DOMEntityReferenceノードとして取得できなくなるため注意が必要です。同様に、getElementsByTagNameで取得した要素も存在しない場合があるため、item(0)の結果がnullでないか確認すると、より安全なプログラムになります。