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

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

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

作成日: 更新日:

基本的な使い方

adoptNodeメソッドは、他のドキュメントオブジェクトに属しているノードを、現在のドキュメントに移動させるために実行するメソッドです。この操作はノードの「養子縁組」とも呼ばれ、指定されたノードを元のドキュメントから完全に削除し、現在のドキュメントが所有するように変更します。これにより、異なる二つのドキュメント間でノードを安全に再配置することが可能になります。似た機能を持つimportNodeメソッドがノードのコピーを作成するのに対し、adoptNodeはノードそのものを移動させるという点が大きな違いです。したがって、元のドキュメントからノードを完全に取り除き、別のドキュメントに移したい場合に使用します。このメソッドで取り込んだノードは、現在のドキュメントに所有権が移りますが、ドキュメントツリー内の特定の位置に自動的に挿入されるわけではありません。そのため、取り込んだ後にはappendChildinsertBeforeなどのメソッドを使用して、明示的にドキュメント内の適切な場所に追加する処理が必要です。処理が成功した場合は移動したノードオブジェクトを返し、失敗した場合はfalseを返します。

構文(syntax)

1<?php
2
3// 移動元のXMLドキュメントを作成
4$sourceDoc = new Dom\XMLDocument();
5$sourceDoc->loadXML('<root><child>move me</child></root>');
6
7// 移動先のXMLドキュメントを作成
8$destDoc = new Dom\XMLDocument();
9$destDoc->loadXML('<newRoot/>');
10
11// 移動するノードを取得
12$nodeToAdopt = $sourceDoc->getElementsByTagName('child')->item(0);
13
14// destDocがnodeToAdoptを自身のノードとして養子縁組する
15// 戻り値は、養子縁組されたノード
16$adoptedNode = $destDoc->adoptNode($nodeToAdopt);
17
18// 養子縁組に成功した場合、移動先のドキュメントに追加する
19if ($adoptedNode) {
20    $destDoc->documentElement->appendChild($adoptedNode);
21}
22
23?>

引数(parameters)

Dom\Node $node

  • Dom\Node $node: 採用したいDOMノードオブジェクト

戻り値(return)

Dom\Node|false

Dom\XMLDocument::adoptNodeメソッドは、別のドキュメントからノードを現在のドキュメントに移動またはコピーして取り込むために使用します。成功した場合は、取り込まれたDom\Nodeオブジェクトを返します。失敗した場合は、falseを返します。

サンプルコード

PHP DomDocumentでノードを移動する

1<?php
2
3/**
4 * 2つのDom\XMLDocumentドキュメント間でノードを移動させるサンプルコードです。
5 * Dom\XMLDocument::adoptNode メソッドを使用して、あるドキュメントから別のドキュメントへ
6 * ノードの所有権を移譲する方法を示します。
7 */
8function demonstrateAdoptNode(): void
9{
10    // ドキュメント1を初期化し、XMLコンテンツを読み込む
11    // ここからノードを「採用」します。
12    $doc1 = new Dom\XMLDocument();
13    $doc1->loadXML('<root><item id="item1">ノード1</item><other>別のノード</other></root>');
14
15    // ドキュメント2を初期化する
16    // ここにノードを「採用」します。
17    $doc2 = new Dom\XMLDocument();
18    $doc2->loadXML('<container></container>');
19
20    echo "--- adoptNode 実行前 ---" . PHP_EOL;
21    echo "Doc1の内容:" . PHP_EOL . $doc1->saveXML() . PHP_EOL;
22    echo "Doc2の内容:" . PHP_EOL . $doc2->saveXML() . PHP_EOL;
23
24    // ドキュメント1から採用したいノードを取得する
25    // ここでは、最初の'item'要素を取得します。
26    // getElementsByTagNameは指定されたタグ名の要素のリストを返します。
27    // item(0)はそのリストの最初の要素を意味します。
28    $nodeToAdopt = $doc1->getElementsByTagName('item')->item(0);
29
30    // ノードが正常に取得できたか確認
31    if ($nodeToAdopt instanceof Dom\Node) {
32        // ドキュメント2にノードを採用する
33        // adoptNodeは元のドキュメント ($doc1) からノードを自動的に削除し、
34        // 新しいドキュメント ($doc2) の所有とするノードを返します。
35        $adoptedNode = $doc2->adoptNode($nodeToAdopt);
36
37        // adoptNodeが成功したか確認(失敗するとfalseを返す)
38        if ($adoptedNode !== false) {
39            // 採用したノードをドキュメント2のルート要素 (<container>) に追加する
40            // appendChildは指定したノードを子ノードとして追加します。
41            $doc2->documentElement->appendChild($adoptedNode);
42
43            echo PHP_EOL . "--- adoptNode 実行後 ---" . PHP_EOL;
44            echo "Doc1の内容 (ノードが移動した):" . PHP_EOL . $doc1->saveXML() . PHP_EOL;
45            echo "Doc2の内容 (ノードが追加された):" . PHP_EOL . $doc2->saveXML() . PHP_EOL;
46        } else {
47            echo PHP_EOL . "エラー: ノードの採用に失敗しました。" . PHP_EOL;
48        }
49    } else {
50        echo PHP_EOL . "エラー: 採用するノード('item'要素)がDoc1に見つかりませんでした。" . PHP_EOL;
51        echo "XML構造を確認してください。" . PHP_EOL;
52    }
53}
54
55// サンプル関数を実行
56demonstrateAdoptNode();

Dom\XMLDocument::adoptNodeメソッドは、異なるXMLドキュメント間でノードの所有権を移すために使用されます。このメソッドは、指定されたDom\Nodeオブジェクトを元のドキュメントから切り離し、呼び出し元のDom\XMLDocumentオブジェクトの所有とします。

このサンプルコードは、二つのDom\XMLDocumentオブジェクトを用意し、片方のドキュメントから別のドキュメントへXMLノードを移動させる一連の流れを示しています。まず、$doc1というドキュメントに初期XMLコンテンツを読み込み、$doc2という別のドキュメントには空のコンテナ要素を持つXMLを準備します。

adoptNodeメソッドの引数には、移動させたいDom\Nodeオブジェクトを指定します。サンプルでは、$doc1からgetElementsByTagName('item')->item(0)を使って「item」要素ノードを取得しています。このノードを$doc2->adoptNode()の引数として渡すことで、このノードの所有権は$doc1から$doc2へと移譲されます。メソッドは成功した場合、採用されたノード自身をDom\Nodeオブジェクトとして返し、失敗した場合はfalseを返します。重要な点として、元のドキュメントからはノードが自動的に削除されます。

ノードの所有権が$doc2に移った後、サンプルでは返されたノードを$doc2->documentElement->appendChild()を使って$doc2のルート要素に追加しています。これにより、実行前後のドキュメントの出力比較を通じて、指定したノードが$doc1から消え、$doc2に正しく追加されていることを確認できます。この機能は、複数のXMLデータから必要な部分を抜き出して新しいXMLデータを作成する場面などで有効です。

Dom\XMLDocument::adoptNodeは、指定したノードを元のドキュメントから完全に移動させ、新しいドキュメントの所有とします。元のドキュメントからはノードが自動で削除されるため、意図しない情報欠落がないか注意してください。ノードを採用しただけでは新しいドキュメント内に自動で追加されません。必ずappendChildなどのメソッドを使って、新しい親ノードの子として明示的に追加する必要があります。また、adoptNodeは成功時に移動したノード、失敗時にfalseを返しますので、戻り値を必ず確認し、適切なエラー処理を実装することが重要です。これにより、安全で堅牢なコードが書けます。

PHP Dom\XMLDocument::adoptNodeでノードを移動する

1<?php
2
3/**
4 * Dom\XMLDocument::adoptNode メソッドの基本的な使い方を示すサンプルコードです。
5 * このメソッドは、別のXMLドキュメントからノードを「養子縁組」し、
6 * 現在のドキュメントで利用できるようにします。
7 *
8 * PHP 8 以降で推奨される Dom\XMLDocument クラスを使用しています。
9 */
10function demonstrateAdoptNode(): void
11{
12    // 1. 最初のXMLドキュメントを作成し、ノードを追加します。
13    $doc1 = new Dom\XMLDocument();
14    $doc1->loadXML('<root1><item id="1">Node from Document 1</item></root1>');
15
16    // 2. 2番目のXMLドキュメントを作成します。
17    $doc2 = new Dom\XMLDocument();
18    $doc2->loadXML('<root2><initialPlaceholder/></root2>');
19
20    // adoption前の各ドキュメントの内容を出力して状態を確認します。
21    echo "--- Adoption前のドキュメントの状態 ---\n";
22    echo "Document 1:\n" . $doc1->saveXML() . "\n\n";
23    echo "Document 2:\n" . $doc2->saveXML() . "\n\n";
24
25    // 3. Document 1から移動したいノード(<item>要素)を取得します。
26    // getElementsByTagNameはNodeListを返すため、item(0)で最初の要素を取得します。
27    $nodeToAdopt = $doc1->getElementsByTagName('item')->item(0);
28
29    // ノードが取得できなかった場合のチェック
30    if ($nodeToAdopt === null) {
31        echo "エラー: Document 1から'item'ノードが見つかりませんでした。\n";
32        return;
33    }
34
35    // 4. adoptNodeメソッドを使用して、取得したノードをDocument 2に移動します。
36    // 成功した場合、新しいDocument 2に属するノードオブジェクトが返されます。
37    // 元のDocument 1からはこのノードが削除されます。
38    $adoptedNode = $doc2->adoptNode($nodeToAdopt);
39
40    if ($adoptedNode !== false) {
41        // adoptNodeが成功した場合、そのノードをDocument 2の適切な場所に挿入します。
42        // ここではDocument 2の<root2>要素の末尾に追加する例です。
43        $root2 = $doc2->getElementsByTagName('root2')->item(0);
44        if ($root2 !== null) {
45            $root2->appendChild($adoptedNode);
46            echo "ノードが正常にDocument 2に採用され、追加されました。\n\n";
47        } else {
48            echo "エラー: Document 2に<root2>要素が見つからず、採用されたノードを追加できませんでした。\n\n";
49        }
50    } else {
51        echo "ノードの採用に失敗しました。\n\n";
52    }
53
54    // adoption後の各ドキュメントの内容を出力して状態を確認します。
55    echo "--- Adoption後のドキュメントの状態 ---\n";
56    echo "Document 1:\n" . $doc1->saveXML() . "\n\n"; // Document 1からは<item>ノードが消えているはずです。
57    echo "Document 2:\n" . $doc2->saveXML() . "\n";   // Document 2には<item>ノードが追加されているはずです。
58}
59
60// サンプル関数の実行
61demonstrateAdoptNode();

Dom\XMLDocument::adoptNodeメソッドは、PHP 8で提供されるXML操作の機能の一つで、あるXMLドキュメントに存在するノードを、別のXMLドキュメントに「養子縁組」させるために使用されます。この機能により、ノードの所属ドキュメントを切り替え、異なるドキュメント間でノードを移動させることが可能になります。

このメソッドは引数としてDom\Node $nodeを受け取ります。これは、現在とは異なるドキュメントに属しているが、現在のドキュメントで利用したいノードオブジェクトを指します。メソッドが成功した場合、新しいドキュメントに属するDom\Nodeオブジェクトが返されます。このとき、元のドキュメントからは指定されたノードが自動的に削除されます。もし処理に失敗した場合はfalseが戻り値となります。

サンプルコードでは、二つのXMLドキュメント($doc1$doc2)を作成し、まず$doc1<item>ノードを追加します。次に、$doc1からその<item>ノードを取得し、$doc2->adoptNode()メソッドを使ってノードを$doc2に移動させます。移動が成功すると、$doc1からは<item>ノードが消え、$doc2に採用されたノードが返されます。その後、返されたノードを$doc2<root2>要素の末尾に追加することで、実際にドキュメント構造を更新しています。この一連の操作により、XMLドキュメント間で要素を柔軟に再配置できるため、異なるXMLデータを統合する際などに役立ちます。

Dom\XMLDocument::adoptNodeメソッドは、別のXMLドキュメントに存在するノードを現在のドキュメントへ完全に移動させる機能です。これはノードのコピーではなく、元のドキュメントからは該当ノードが削除され、現在のドキュメントに所有権が移転する点にご注意ください。

メソッドの戻り値は、ノードの採用が成功した場合は現在のドキュメントに属する新しいノードオブジェクト、失敗した場合はfalseとなります。そのため、必ず戻り値をチェックし、falseでないことを確認してからノードを利用してください。採用されたノードは、そのままではドキュメントツリー内に配置されません。採用後にappendChildなどのDOMメソッドを使用し、目的の場所に明示的に挿入する必要があります。

また、getElementsByTagNameのようなメソッドはノードのリストを返しますので、特定のノードを取得する際はitem(0)のようにインデックスを指定して取り出す必要があります。その際、指定したノードが存在しない場合はnullが返されるため、nullチェックを行い、安全に処理を進めることが重要です。

関連コンテンツ

関連プログラミング言語