Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】Dom\EntityReference::getRootNode()メソッドの使い方

getRootNodeメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

『getRootNodeメソッドは、現在のDom\EntityReferenceノードが属するDOMツリーのルートノードを取得する処理を実行するメソッドです。DOMにおいて、HTMLやXMLドキュメントは、要素やテキストといった各部分(ノード)が親子関係を持つ階層構造(ツリー)として扱われます。このメソッドは、そのツリー構造における最上位のノード、すなわちドキュメントの根元となるノードを返します。通常、返されるのはドキュメント全体を表すDom\Documentオブジェクトです。この機能により、例えばドキュメント内の特定のエンティティ参照を表すノードから、そのドキュメント全体の文字エンコーディングや他の要素へアクセスするといった操作が可能になります。なお、対象となるノードがまだどのドキュメントにも追加されておらず、ツリーに属していない孤立した状態の場合、このメソッドはそのノード自身を返します。この挙動は、ノードがドキュメントに正しく組み込まれているかを確認する際にも役立ちます。

構文(syntax)

1<?php
2
3$xml = <<<XML
4<?xml version="1.0" encoding="utf-8" ?>
5<!DOCTYPE doc [
6  <!ENTITY exampleEntity "an entity value">
7]>
8<root>
9  <para>Here is &exampleEntity;.</para>
10</root>
11XML;
12
13$doc = new DOMDocument();
14$doc->loadXML($xml);
15
16// <para>要素の子ノードリストから Dom\EntityReference オブジェクトを取得
17$entityRef = $doc->getElementsByTagName('para')->item(0)->childNodes->item(1);
18
19// Dom\EntityReference::getRootNode() の構文
20// このノードが含まれるツリーのルートノードを取得します。
21$rootNode = $entityRef->getRootNode();
22
23// 取得したノードがドキュメントオブジェクト自身であることを確認
24var_dump($rootNode === $doc); // bool(true)
25echo $rootNode->nodeName;     // #document
26
27?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

Dom\Node

Dom\EntityReference オブジェクトが参照している DOM ツリーのルートノードを Dom\Node オブジェクトとして返します。

サンプルコード

Dom\EntityReference::getRootNode()でルートノードを取得する

1<?php
2
3// Dom\EntityReference::getRootNode() のサンプルコード
4// このメソッドは、Dom\EntityReference ノードが属する最上位のノード(通常は Dom\Document オブジェクト)を返します。
5
6// 1. 新しい XML ドキュメントを表す Dom\Document オブジェクトを作成します。
7$document = new Dom\Document();
8
9// 2. ドキュメントのルート要素(最上位の要素)を作成し、ドキュメントに追加します。
10$rootElement = $document->createElement('exampleRoot');
11$document->appendChild($rootElement);
12
13// 3. エンティティ参照ノードを作成します。
14//    'myEntity' は参照されるエンティティの名前です。
15$entityReference = $document->createEntityReference('myEntity');
16
17// 4. 作成したエンティティ参照ノードをドキュメントツリーのルート要素の子として追加します。
18$rootElement->appendChild($entityReference);
19
20// 5. Dom\EntityReference オブジェクトに対して getRootNode() メソッドを呼び出します。
21//    これにより、このエンティティ参照が属するドキュメントのルートノードが取得されます。
22$rootNode = $entityReference->getRootNode();
23
24// 6. 取得したルートノードのクラス名を表示します。
25//    通常、これは Dom\Document クラスのインスタンスになります。
26echo "取得したルートノードのクラス: " . get_class($rootNode) . PHP_EOL;
27
28// 7. 取得したルートノードが、最初に作成した Dom\Document オブジェクトと厳密に同一であるか確認します。
29if ($rootNode === $document) {
30    echo "確認: ルートノードは、このエンティティ参照が属する Dom\Document オブジェクトと同一です。" . PHP_EOL;
31} else {
32    echo "エラー: 想定外のルートノードが返されました。" . PHP_EOL;
33}
34

Dom\EntityReference::getRootNode() メソッドは、XMLドキュメント内で定義されたエンティティ参照(Dom\EntityReference)が、どのドキュメントに属しているか、その最上位のノードを取得するために使用されます。このメソッドは引数を必要としません。

戻り値は Dom\Node 型のオブジェクトであり、具体的には、当該エンティティ参照ノードが組み込まれているドキュメントのルート(最上位)ノード、通常は Dom\Document オブジェクトのインスタンスを返します。

サンプルコードでは、まず新しい Dom\Document を作成し、ルート要素とエンティティ参照ノードをそのドキュメントに追加しています。その後、作成したエンティティ参照に対して getRootNode() を呼び出すことで、このエンティティ参照が属する Dom\Document オブジェクト自身が取得されることを示しています。最終的に、取得されたノードが元の Dom\Document オブジェクトと同一であるかを検証し、このメソッドが期待通りに最上位のドキュメントノードを返すことを確認しています。これにより、エンティティ参照からその親ドキュメントへ簡単にアクセスできるようになります。

Dom\EntityReference::getRootNode()は、対象のエンティティ参照ノードが所属する最上位のノード、通常はDom\Documentオブジェクトを返します。サンプルコードのように、createEntityReferenceで作成したノードをappendChildなどでDOMツリーに正しく追加してからこのメソッドを呼び出すことが重要です。

ツリーに所属していないノードに対して呼び出した場合、期待通りのDom\Documentが返されない可能性があります。このメソッドは、あくまで現在のノードが属するドキュメントのルートを特定するために利用し、途中の親ノードが返されることはありません。XMLパース時にエンティティが解決される前の「参照」ノードから、その参照元であるドキュメント全体を把握するのに役立ちます。常にDom\Documentインスタンスが返るため、返り値の型を想定しやすいです。

Dom\EntityReference::getRootNode()でルートノードを取得する

1<?php
2
3/**
4 * Demonstrates the use of Dom\EntityReference::getRootNode().
5 *
6 * This function creates an XML document with an entity reference,
7 * finds that entity reference node, and then calls getRootNode() on it
8 * to show that it returns the Dom\Document itself.
9 *
10 * For an entity reference to exist as a distinct node, DOMDocument::substituteEntities
11 * must be set to false before loading the XML.
12 */
13function demonstrateEntityReferenceGetRootNode(): void
14{
15    // 1. Create a new DOMDocument instance.
16    $dom = new DOMDocument('1.0', 'UTF-8');
17
18    // 2. Disable entity substitution.
19    //    This is crucial to prevent entity references from being expanded
20    //    into their content, allowing them to exist as Dom\EntityReference nodes.
21    $dom->substituteEntities = false;
22
23    // 3. Define an XML string with a DTD and an entity reference.
24    $xmlString = <<<XML
25<?xml version="1.0" encoding="UTF-8"?>
26<!DOCTYPE root [
27  <!ENTITY exampleEntity "Hello World">
28]>
29<root>
30  <message>Here is an entity: &exampleEntity;!</message>
31</root>
32XML;
33
34    // 4. Load the XML string into the DOMDocument.
35    $dom->loadXML($xmlString);
36
37    // 5. Traverse the document to find the Dom\EntityReference node.
38    //    Entity references are typically children of text nodes or elements.
39    $foundEntityReference = null;
40    foreach ($dom->getElementsByTagName('message') as $messageElement) {
41        foreach ($messageElement->childNodes as $node) {
42            // Check if the node is an entity reference node type.
43            // In PHP 8, DOM extension objects belong to the Dom namespace.
44            // XML_ENTITY_REF_NODE is a constant for the node type.
45            if ($node->nodeType === XML_ENTITY_REF_NODE) {
46                // Cast or ensure it's treated as a Dom\EntityReference
47                // PHP's internal DOM classes implement the Dom interfaces automatically.
48                $foundEntityReference = $node;
49                break 2; // Exit both loops once found
50            }
51        }
52    }
53
54    // 6. If an entity reference node was found, demonstrate getRootNode().
55    if ($foundEntityReference instanceof Dom\EntityReference) {
56        echo "Found Dom\\EntityReference node named: '{$foundEntityReference->nodeName}'" . PHP_EOL;
57
58        // Call getRootNode() on the entity reference.
59        // This method returns the root node of the document tree to which this node belongs.
60        $rootNode = $foundEntityReference->getRootNode();
61
62        echo "Called getRootNode() on the entity reference." . PHP_EOL;
63
64        // 7. Verify the returned node.
65        // For any node within a Dom\Document, getRootNode() should return the Dom\Document itself.
66        if ($rootNode instanceof Dom\Document) {
67            echo "The returned root node is an instance of Dom\\Document." . PHP_EOL;
68            echo "Document version: " . ($rootNode->xmlVersion ?? 'N/A') . PHP_EOL;
69            echo "Document encoding: " . ($rootNode->xmlEncoding ?? 'N/A') . PHP_EOL;
70        } else {
71            echo "The returned root node is of unexpected type: " . get_class($rootNode) . PHP_EOL;
72        }
73    } else {
74        echo "Could not find a Dom\\EntityReference node. Make sure 'substituteEntities' is false and the XML contains an entity reference." . PHP_EOL;
75    }
76}
77
78// Execute the demonstration function.
79demonstrateEntityReferenceGetRootNode();
80

PHP 8のDom\EntityReference::getRootNode()メソッドは、XMLドキュメント内のエンティティ参照ノードが属するドキュメントツリーの「ルートノード」を取得するために使用されます。このメソッドは引数を一切取りません。戻り値はDom\Node型ですが、ドキュメント内のノードに対して呼び出された場合、通常はXMLドキュメント全体を表すDom\Documentオブジェクトそのものが返されます。

提供されたサンプルコードでは、まずDOMDocumentインスタンスを作成し、substituteEntitiesプロパティをfalseに設定しています。この設定は、XML内のエンティティ参照(例: &exampleEntity;)がその実体(例: "Hello World")に展開されず、DOMツリー内で独立したDom\EntityReferenceノードとして存在するために不可欠です。次に、DTD(Document Type Definition)で定義されたエンティティを含むXMLを読み込みます。

コードは、読み込んだXMLドキュメントの中から目的のDom\EntityReferenceノードを探し出します。エンティティ参照ノードが見つかったら、そのノードに対してgetRootNode()メソッドを呼び出します。この呼び出しにより、エンティティ参照ノードが属するドキュメントのルート(つまり、DOMDocumentオブジェクト自身)が返されることを確認できます。このメソッドは、特定のノードがどのXMLドキュメントに属しているかを確認する際に役立ちます。

Dom\EntityReference::getRootNode()を使用する際、最も重要なのは、XMLを読み込む前に$dom->substituteEntities = false;を設定することです。これを設定しないと、エンティティ参照が展開され、Dom\EntityReferenceノードとして取得できなくなります。getRootNode()メソッドは、このエンティティ参照ノードが属するXML文書全体のルートノード、すなわちDom\Documentオブジェクトを返します。これにより、XML文書内のどこにあるノードからでも、文書全体の情報を参照できることを理解しましょう。エンティティ参照ノードを探す際には、サンプルコードのようにnodeTypeXML_ENTITY_REF_NODEであるかをチェックする方法が確実です。

関連コンテンツ

関連IT用語

関連プログラミング言語