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

【PHP8.x】DOMEntity::ownerDocumentプロパティの使い方

ownerDocumentプロパティの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

ownerDocumentプロパティは、そのDOMEntityインスタンスが属するDOMDocumentオブジェクトを保持するプロパティです。PHPのDOM拡張において、DOMEntityクラスはXMLドキュメント内で宣言された実体(エンティティ)を表すノードです。XMLドキュメントを構成するすべてのノードは、必ず一つのDOMDocumentオブジェクトに属しており、このownerDocumentプロパティを利用することで、特定のDOMEntityがどのドキュメントのコンテキストで存在しているのかを知ることができます。

このプロパティは、例えばXMLドキュメントの一部である実体定義から、その実体が属するドキュメント全体の操作や、ドキュメント内の他の要素へのアクセスが必要な場合に非常に役立ちます。DOMEntityノードから直接、親となるDOMDocumentオブジェクトにアクセスできるため、ドキュメント全体の構造を調べたり、異なるノード間の関連性を辿ったりする際の起点として活用できます。このプロパティが保持するDOMDocumentオブジェクトは、XMLドキュメント全体を表現するルートノードであり、これにより柔軟なプログラミングが可能になります。

構文(syntax)

1<?php
2$dom = new DOMDocument();
3$xmlString = '<!DOCTYPE root [<!ENTITY example "Hello">]><root>&example;</root>';
4$dom->loadXML($xmlString);
5
6$entity = $dom->entities->getNamedItem('example');
7
8if ($entity instanceof DOMEntity) {
9    $ownerDocument = $entity->ownerDocument;
10    var_dump($ownerDocument === $dom);
11}

引数(parameters)

引数なし

引数はありません

戻り値(return)

?DOMDocument

このプロパティは、このエンティティが属するDOMDocumentオブジェクトを返します。エンティティがDOMツリーに属していない場合はNULLを返します。

サンプルコード

DOMEntityのownerDocumentからDOMDocumentを取得してsaveHTMLする

1<?php
2
3/**
4 * DOMEntity の ownerDocument プロパティの使用例を示します。
5 * ownerDocument プロパティは、ノードが属する DOMDocument オブジェクトを返します。
6 * その後、返された DOMDocument オブジェクトに対して saveHTML メソッドを使用します。
7 *
8 * DOMEntity オブジェクトは通常、DTD (Document Type Definition) で定義された
9 * エンティティを参照するために使用されます。HTMLでは直接DOMツリーに現れることは
10 * 稀なため、ここでは DTD を含む XML ドキュメントを使用します。
11 */
12function demonstrateDomEntityOwnerDocument(): void
13{
14    // DTD で 'myentity' という名前のエンティティを定義した XML 文字列
15    $xmlString = <<<XML
16<!DOCTYPE root [
17  <!ENTITY myentity "Hello from DOMEntity!">
18]>
19<root>
20  <description>This is a test document using &myentity;</description>
21</root>
22XML;
23
24    // 新しい DOMDocument オブジェクトを作成
25    $dom = new DOMDocument();
26    // XML 文字列をロード
27    $dom->loadXML($xmlString);
28
29    // ドキュメントタイプ (DOCTYPE) を取得
30    $doctype = $dom->doctype;
31    $myEntity = null;
32
33    // ドキュメントタイプが存在し、エンティティコレクションがあるか確認
34    if ($doctype instanceof DOMDocumentType && $doctype->entities) {
35        // DTD で定義された 'myentity' という名前の DOMEntity オブジェクトを取得
36        // entities は DOMNamedNodeMap であり、getNamedItem() で名前を指定して要素を取得
37        $myEntity = $doctype->entities->getNamedItem('myentity');
38    }
39
40    // DOMEntity オブジェクトが取得できたか確認
41    if ($myEntity instanceof DOMEntity) {
42        echo "--- 取得した DOMEntity の情報 ---\n";
43        echo "エンティティ名: " . $myEntity->nodeName . "\n";
44        echo "エンティティ値: " . $myEntity->nodeValue . "\n\n";
45
46        // DOMEntity の ownerDocument プロパティにアクセス
47        // これは DOMEntity が属する DOMDocument オブジェクトを返します
48        $ownerDocument = $myEntity->ownerDocument;
49
50        // ownerDocument が DOMDocument のインスタンスであるか確認
51        if ($ownerDocument instanceof DOMDocument) {
52            echo "--- ownerDocument の情報 ---\n";
53            echo "ownerDocument は DOMDocument のインスタンスです。\n";
54
55            // ownerDocument (DOMDocument) オブジェクトの saveHTML メソッドを使用して、
56            // ドキュメント全体の HTML (この場合はXMLをHTMLとして出力) を取得し表示
57            // XMLドキュメントに対して saveHTML() を呼び出すと、XML宣言を含むXML文字列を返します。
58            echo "ownerDocument の内容 (saveHTML() による出力):\n";
59            echo $ownerDocument->saveHTML() . "\n";
60        } else {
61            echo "エラー: ownerDocument が DOMDocument のインスタンスではありません。\n";
62        }
63    } else {
64        echo "エラー: 'myentity' という名前の DOMEntity が見つかりませんでした。\n";
65    }
66}
67
68// 関数を実行
69demonstrateDomEntityOwnerDocument();
70

DOMEntityクラスのownerDocumentプロパティは、特定のノードがどのDOMDocumentオブジェクトに属しているかを特定するためのものです。このプロパティは引数を取らず、戻り値としてノードが属するDOMDocumentオブジェクト、またはノードがDOMDocumentに属していない場合はnullを返します。DOMEntityは通常、HTMLドキュメントではあまり使用されませんが、XMLのDTD(Document Type Definition)内で定義されるエンティティ(例: &myentity; のような記号)を表現する際に用いられます。

サンプルコードでは、DTDで「myentity」を定義したXMLドキュメントを作成し、そこからDOMEntityオブジェクトを取得しています。この取得したDOMEntityオブジェクトのownerDocumentプロパティにアクセスすると、そのエンティティが存在する元のDOMDocumentオブジェクトが得られます。このDOMDocumentオブジェクトは、ドキュメント全体の構造や内容を管理する核となるインスタンスです。次に、この取得したownerDocument(つまりDOMDocumentオブジェクト)に対してsaveHTML()メソッドを呼び出しています。saveHTML()は、DOMDocumentオブジェクトが持つドキュメント全体をHTML(この例のようにXMLドキュメントの場合はXML)形式の文字列として出力するメソッドです。これにより、特定のDOMEntityから、それが属するドキュメント全体の内容を確認し、文字列として取得できることが示されます。この一連の操作は、DOMツリー内の任意のノードから、そのノードが属する親ドキュメント全体に簡単にアクセスし、その内容を操作したり表示したりする際に非常に有用です。

DOMEntityはHTMLドキュメントでは通常現れず、DTDを持つXMLドキュメントでエンティティとして使用される特殊なノードです。ownerDocumentプロパティは、ノードが属するDOMDocumentオブジェクトを返しますが、ノードがドキュメントに属さない場合などはnullを返す可能性があるため、取得後に必ずDOMDocumentのインスタンスであるかを確認する型チェックが重要です。また、XMLドキュメントに対してsaveHTMLメソッドを使用すると、HTMLとしてではなく、XML宣言を含む元のXML文字列が出力されますので、出力形式に注意が必要です。これらの戻り値の型確認やエラーハンドリングは、コードの安全性と信頼性を高める上で非常に重要となります。

DOMEntity の ownerDocument でドキュメントを取得する

1<?php
2
3/**
4 * DOMEntity の ownerDocument プロパティの使用例を示します。
5 *
6 * この関数は、XML ドキュメント内に定義されたエンティティを作成し、
7 * そのエンティティが属するドキュメントオブジェクト (DOMDocument) を
8 * ownerDocument プロパティを通じて取得する方法を示します。
9 *
10 * システムエンジニアを目指す初心者向けに、DOMツリーの基本とプロパティの役割を解説します。
11 */
12function demonstrateDomEntityOwnerDocument(): void
13{
14    // 1. XML ドキュメントを作成します。
15    // ここでは、DOCTYPE 宣言内にカスタムエンティティ 'copyright' を定義したXML文字列を使用します。
16    // エンティティは、特定の文字列のショートカットとして定義されます(例: &copyright;)。
17    $xmlString = <<<XML
18<!DOCTYPE root [
19    <!ENTITY copyright "Copyright © 2023 Example Corp.">
20]>
21<root>
22    <text>&copyright; All rights reserved.</text>
23</root>
24XML;
25
26    // DOMDocument オブジェクトは、XML/HTML ドキュメント全体を表します。
27    $dom = new DOMDocument();
28    // loadXML() メソッドでXML文字列を解析し、DOMツリーを構築します。
29    $dom->loadXML($xmlString);
30
31    echo "--- ドキュメント情報 ---\n";
32    echo "ドキュメントの XML バージョン: " . $dom->xmlVersion . "\n";
33    echo "ドキュメントのエンコーディング: " . $dom->xmlEncoding . "\n\n";
34
35    // 2. ドキュメントタイプ (DOCTYPE) ノードを取得します。
36    // XML ドキュメントの DOCTYPE 宣言は、ドキュメントの構造やエンティティを定義します。
37    // DOMDocument の doctype プロパティは DOMDocumentType オブジェクトを返します。
38    $docType = $dom->doctype;
39
40    if ($docType === null) {
41        echo "エラー: DOCTYPE が見つかりませんでした。エンティティにアクセスできません。\n";
42        return;
43    }
44
45    echo "--- DOCTYPE 情報 ---\n";
46    echo "DOCTYPE の名前: " . $docType->name . "\n\n";
47
48    // 3. DOCTYPE に含まれるエンティティのコレクションを取得し、特定のエンティティを選択します。
49    // DOMDocumentType の entities プロパティは、DOMNamedNodeMap オブジェクトを返します。
50    // これは、エンティティ名をキーとして DOMEntity オブジェクトを保持するマップです。
51    $entities = $docType->entities;
52
53    if ($entities === null || $entities->count() === 0) {
54        echo "エラー: ドキュメントにエンティティが定義されていません。\n";
55        return;
56    }
57
58    // getNamedItem() メソッドで、定義した 'copyright' エンティティを取得します。
59    /** @var DOMEntity|null $copyrightEntity */
60    $copyrightEntity = $entities->getNamedItem('copyright');
61
62    if ($copyrightEntity === null) {
63        echo "エラー: 'copyright' エンティティが見つかりませんでした。\n";
64        return;
65    }
66
67    echo "--- DOMEntity 情報 ---\n";
68    echo "エンティティ名: " . $copyrightEntity->nodeName . "\n";
69    echo "エンティティの値: " . $copyrightEntity->nodeValue . "\n\n";
70
71    // 4. DOMEntity の ownerDocument プロパティにアクセスします。
72    // ownerDocument プロパティは、そのノード(この場合は DOMEntity)が属している
73    // 最上位の DOMDocument オブジェクトを返します。
74    // これは、ノードがどのドキュメントに「所有されている」かを示すものです。
75    $ownerDoc = $copyrightEntity->ownerDocument;
76
77    echo "--- ownerDocument プロパティの結果 ---\n";
78    if ($ownerDoc instanceof DOMDocument) {
79        echo "ownerDocument は DOMDocument オブジェクトです。\n";
80        echo "ownerDocument の XML バージョン: " . $ownerDoc->xmlVersion . "\n";
81
82        // 取得した ownerDocument オブジェクトが、最初に作成した $dom オブジェクトと
83        // 全く同一のインスタンスであるかを確認します。
84        if ($ownerDoc === $dom) {
85            echo "ownerDocument は、元の DOMDocument オブジェクトと同一のインスタンスです。\n";
86        } else {
87            echo "ownerDocument は元の DOMDocument オブジェクトと異なります (これは予期しない動作です)。\n";
88        }
89    } else {
90        // ?DOMDocument の戻り値型にもかかわらず、DOMEntity は常に DOMDocument に属するため、
91        // このパスに到達することは通常ありません。
92        echo "ownerDocument は DOMDocument オブジェクトではありません。\n";
93    }
94}
95
96// サンプル関数を実行して、DOMEntity の ownerDocument プロパティの動作を確認します。
97demonstrateDomEntityOwnerDocument();
98
99?>

PHPのDOM拡張機能は、XMLやHTMLドキュメントをプログラムで操作するための機能を提供します。DOMEntity::ownerDocumentプロパティは、DOMEntityオブジェクトがどのDOMDocumentオブジェクトに「所属しているか」を取得するために使用されます。

DOMEntityは、XMLドキュメントのDOCTYPE宣言内で定義される特定の文字列(エンティティ)を表すオブジェクトです。一方、DOMDocumentは、XMLドキュメント全体を管理する最上位のオブジェクトです。

このownerDocumentプロパティは、引数を一切取りません。その役割は、現在のDOMEntityオブジェクトが構築されている元のDOMDocumentオブジェクトを特定し、それを戻り値として返します。戻り値の型は?DOMDocumentであり、通常は所属するDOMDocumentオブジェクトが返されますが、特定の条件下でnullを返す可能性も理論上存在します。

サンプルコードでは、XML内に定義されたcopyrightというエンティティを取得し、そのDOMEntityオブジェクトからownerDocumentプロパティを使って、元のDOMDocumentオブジェクトを取り出しています。そして、取得したownerDocumentが、最初に作成したDOMDocumentオブジェクトと同一であることを確認しています。これにより、DOMツリー内のどのノードからでも、そのノードが属するドキュメント全体を簡単に参照できることがわかります。

ownerDocumentプロパティは、DOMノードがどのDOMDocumentオブジェクトに所属するかを示す基本的な情報です。リファレンスで?DOMDocumentとあるように、理論上はnullになる可能性もゼロではありませんが、適切に構築されたDOMツリー内のDOMEntityでは通常DOMDocumentインスタンスが返されます。しかし、DOMを扱う際は常にnullチェックを行い、予期せぬエラーを防ぐ習慣をつけることが大切です。

サンプルコードはDOMDocumentからDOMDocumentTypeDOMNamedNodeMapを経由してDOMEntityを取得する一連の流れを示しています。これはDOMツリーの階層構造と、異なるオブジェクト型がどのように連携するかを理解する良い練習になります。それぞれのプロパティやメソッドがどの型のオブジェクトを返すか意識し、その役割を把握することが、DOM操作を学ぶ上で役立ちます。また、XMLのDOCTYPE宣言によるエンティティ定義も確認し、DOM操作の基礎を固めてください。

関連コンテンツ

関連IT用語

関連プログラミング言語