【PHP8.x】importNodeメソッドの使い方
importNodeメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
importNodeメソッドは、指定されたノードを別のドキュメントから現在のドキュメントへインポートするメソッドです。
このメソッドは、XMLやHTMLのドキュメントオブジェクトモデル(DOM)を操作する際に非常に重要で、異なるドキュメントに属するノードを、現在作業しているドキュメントのコンテキストで利用できるようにするために使用されます。具体的には、引数として渡されたノード(要素、テキスト、コメントなど)のクローンを作成し、そのクローンを現在のドキュメントに属するものとして返します。元のドキュメント内の元のノードは、変更されることなくそのまま残ります。
importNodeメソッドには、第二引数として$deepというブール値を指定できます。この$deepにtrueを設定した場合、インポート対象のノードだけでなく、そのノードのすべての子孫ノード(子要素やそのさらに子要素など)も再帰的にインポートされ、新しいドキュメントのコンテキストに適合するようクローンされます。一方、$deepにfalseを設定すると、インポート対象のノードのみがインポートされ、その子孫ノードは含まれません。
この機能は、例えば、テンプレートとして作成された別のHTMLドキュメントから特定のセクションや要素を取り出し、現在のHTMLドキュメントに組み込む際などに非常に役立ちます。これにより、異なるドキュメント構造を持つデータを効率的に統合・利用することが可能になります。
構文(syntax)
1<?php 2 3$targetDocument = new Dom\HTMLDocument(); // ノードをインポートする先のHTMLドキュメント 4$sourceDocument = new Dom\HTMLDocument(); // インポート元となるノードを含むHTMLドキュメント 5$sourceDocument->loadHTML('<div><p>インポートするノード</p></div>'); 6 7$nodeToImport = $sourceDocument->getElementsByTagName('p')->item(0); // インポートしたいDom\Nodeオブジェクト 8$deep = true; // ノードの子孫も再帰的にインポートするか (true:する, false:しない) 9 10// Dom\HTMLDocument::importNode メソッドの構文 11$importedNode = $targetDocument->importNode($nodeToImport, $deep); 12 13?>
引数(parameters)
Dom\Node $node, bool $deep = false
- Dom\Node $node: インポートしたいDOMノード
- bool $deep = false: trueの場合、指定したノードの子孫ノードもすべてインポートします。デフォルトはfalseで、ノード自身のみをインポートします。
戻り値(return)
Dom\Node
指定されたDOM (Document Object Model) のノードを、現在のHTMLドキュメントのコンテキストでインポートした新しいノードを返します。この新しいノードは、元のノードの構造と内容を保持していますが、DOMツリー内での配置は異なります。
サンプルコード
PHP Dom\HTMLDocument::importNode でノードをインポートする
1<?php 2 3/** 4 * Dom\HTMLDocument::importNode の使用例を示します。 5 * あるHTMLドキュメントから別のドキュメントへ、特定の要素(ノード)をコピーします。 6 */ 7function domImportNodeExample(): void 8{ 9 // 1. コピー元となるソースHTMLを定義します。 10 $sourceHtml = <<<HTML 11<!DOCTYPE html> 12<html> 13<body> 14 <div id="source-content"> 15 <p>これはコピー元の段落です。<strong>太字</strong>の部分も含まれます。</p> 16 </div> 17</body> 18</html> 19HTML; 20 21 // 2. コピー先となるターゲットHTMLを定義します。 22 $targetHtml = <<<HTML 23<!DOCTYPE html> 24<html> 25<body> 26 <h1>ターゲット文書</h1> 27 <div id="target-container"> 28 <!-- ここにソースの要素が追加されます --> 29 </div> 30</body> 31</html> 32HTML; 33 34 // libxmlのエラーを内部で処理するように設定し、HTML5の解釈エラーが画面に出るのを防ぎます。 35 libxml_use_internal_errors(true); 36 37 // 3. ソースとターゲットのドキュメントオブジェクトを作成します。 38 $sourceDoc = new Dom\HTMLDocument(); 39 $sourceDoc->loadHTML($sourceHtml); 40 41 $targetDoc = new Dom\HTMLDocument(); 42 $targetDoc->loadHTML($targetHtml); 43 44 // 4. ソースドキュメントからコピーしたいノード(<p>要素)を取得します。 45 $nodeToCopy = $sourceDoc->getElementsByTagName('p')->item(0); 46 47 // 5. ターゲットドキュメントにソースのノードをインポートします。 48 // 第2引数に `true` を指定すると、子ノード(この場合は<strong>要素)も再帰的にコピーされます(ディープコピー)。 49 // これを行わないと、別のドキュメントのノードを追加しようとしてエラーになります。 50 $importedNode = $targetDoc->importNode($nodeToCopy, true); 51 52 // 6. ターゲットドキュメントの特定の場所(id="target-container"のdiv)にインポートしたノードを追加します。 53 $container = $targetDoc->getElementById('target-container'); 54 if ($container) { 55 $container->appendChild($importedNode); 56 } 57 58 // 7. 結果として得られたターゲットドキュメントのHTMLを出力します。 59 echo $targetDoc->saveHTML(); 60} 61 62// 関数を実行します。 63domImportNodeExample(); 64
PHPのDom\HTMLDocument::importNodeメソッドは、あるHTMLドキュメントから別のHTMLドキュメントへ、特定の要素(ノード)をコピーするために使用します。異なるドキュメントに属するノードを直接追加することはできないため、このメソッドを使って、追加先ドキュメントに所属するノードとして安全に複製する必要があります。
このメソッドの第1引数には、コピーしたい元のノードを指定します。第2引数はオプションで、trueを指定すると、そのノードが持つ子要素や孫要素もすべて再帰的にコピーします(ディープコピー)。falseを指定したり省略したりした場合は、ノード自身のみがコピーされ、その中身は含まれません。メソッドの戻り値として、コピー先ドキュメントに所属する新しいノードの複製が返されます。
サンプルコードでは、まず2つのHTMLドキュメント(コピー元とコピー先)を準備します。次に、コピー元の<p>要素を取得し、importNodeメソッドでコピー先のドキュメント用に複製しています。このとき、第2引数にtrueを指定しているため、<p>要素の中にある<strong>要素も一緒にコピーされます。最後に、importNodeから返された新しいノードを、コピー先ドキュメントの特定の<div>要素に追加しています。
importNodeメソッドは、異なるHTMLドキュメント間で要素を移動させる際に必須の手順です。あるドキュメントから取得した要素(ノード)を、直接別のドキュメントにappendChildなどで追加しようとするとエラーが発生します。このため、まずimportNodeを使って、移動させたい要素をターゲットのドキュメントに所属する新しい要素としてコピーする必要があります。第2引数にtrueを指定することで、要素の中のテキストや子要素も一緒にコピーできます。コピー後は、改めてappendChildなどを用いて、ドキュメント内の任意の位置に追加する、という2段階の操作が必要になる点に注意してください。