【PHP8.x】Dom\XMLDocument::importNode()メソッドの使い方
importNodeメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
importNodeメソッドは、他のXMLドキュメントに属するノードを、現在のDom\XMLDocumentインスタンスにインポートして、このドキュメントの一部として扱えるようにするメソッドです。このメソッドを利用することで、異なるドキュメントからXMLの要素や属性、テキストなどのノードを取り込み、現在のドキュメント内で操作したり追加したりすることが可能になります。
第一引数には、インポートしたいDOMノードオブジェクトを渡します。第二引数 $deep はオプションで、真偽値 (true または false) を指定します。true を指定すると、対象ノードだけでなく、そのノードの子ノードもすべて再帰的にインポートされます。false または省略した場合、対象ノード自身のみがインポートされ、子ノードは含まれません。
このメソッドは、新しくインポートされ、現在のドキュメントに属するようになったノードオブジェクトを返します。もしインポート処理が失敗した場合は false が返されます。元のドキュメントからノードが移動するのではなく、元のノードはそのまま残り、そのコピーが現在のドキュメント用に作成される点が重要です。複数のXMLデータを組み合わせて一つのドキュメントを構築するような場面で、この機能は大変有用です。
構文(syntax)
1$importedNode = $targetDocument->importNode($sourceNode, $deep);
引数(parameters)
DOMNode $node, bool $deep = false
- DOMNode $node: インポートするDOMNodeオブジェクト
- bool $deep = false: trueを指定すると、指定した$nodeの子要素もすべて再帰的にインポートします。falseの場合、$nodeのみをインポートします。
戻り値(return)
Dom\Node
指定されたXMLノードを、現在のXMLドキュメントにインポートした新しいノードを返します。
サンプルコード
PHP DOMDocument importNodeでノードをインポートする
1<?php 2 3/** 4 * 別のDOMドキュメントからノードをインポートし、現在のドキュメントに追加する例を示します。 5 * Dom\XMLDocument::importNode メソッドの使用方法を説明します。 6 */ 7function importXmlNodeExample(): void 8{ 9 // 1. インポート元のXMLドキュメントを作成します。 10 // このドキュメントには、インポートしたいノードが含まれます。 11 $sourceDocument = new Dom\XMLDocument(); 12 $sourceDocument->loadXML('<items><item id="A">Apple</item><item id="B">Banana</item></items>'); 13 14 // インポートしたいノードを選択します。 15 // ここでは、最初の <item> 要素(Apple)を選択します。 16 $nodeToImport = $sourceDocument->getElementsByTagName('item')->item(0); 17 18 if ($nodeToImport === null) { 19 echo "インポート元のノードが見つかりませんでした。\n"; 20 return; 21 } 22 23 echo "インポート元のノード: " . $sourceDocument->saveXML($nodeToImport) . "\n\n"; 24 25 // 2. インポート先のXMLドキュメントを作成します。 26 // このドキュメントに、別のドキュメントからインポートしたノードを追加します。 27 $targetDocument = new Dom\XMLDocument(); 28 $targetDocument->loadXML('<newRoot></newRoot>'); 29 30 // インポート先のルートノードを取得します。 31 $targetRoot = $targetDocument->getElementsByTagName('newRoot')->item(0); 32 33 if ($targetRoot === null) { 34 echo "インポート先のルートノードが見つかりませんでした。\n"; 35 return; 36 } 37 38 // 3. Dom\XMLDocument::importNode メソッドを使用してノードをインポートします。 39 // このメソッドは、指定されたノードを現在のドキュメント($targetDocument)にコピーし、 40 // 新しいノード(ターゲットドキュメントに属する)を返します。 41 // 42 // 第二引数 $deep は、インポートするノードの子孫も一緒にインポートするかどうかを決定します。 43 // true の場合、ノード自身とそのすべての子孫がインポートされます。 44 // false の場合、ノード自身のみがインポートされ、子孫はインポートされません。 45 $importedNode = $targetDocument->importNode($nodeToImport, true); // trueで子ノードも含めてインポート 46 47 echo "インポートされたノード(まだドキュメントに追加されていません): " . $targetDocument->saveXML($importedNode) . "\n\n"; 48 49 // 4. インポートされたノードをターゲットドキュメントに追加します。 50 // importNodeはノードを「インポート」するだけで、自動的に追加はしません。 51 // appendChild などのメソッドを使用して、明示的に追加する必要があります。 52 $targetRoot->appendChild($importedNode); 53 54 // 5. 結果のXMLを出力します。 55 echo "インポート後のターゲットドキュメントのXML:\n"; 56 echo $targetDocument->saveXML(); 57} 58 59// 関数の実行 60importXmlNodeExample(); 61 62?>
Dom\XMLDocument::importNodeメソッドは、あるXMLドキュメントに属するノードを、別のXMLドキュメントへコピーして取り込むために使用します。XMLノードは通常、作成されたドキュメントにしか所属できないため、異なるドキュメント間でノードを移動させる際にはこのメソッドが必要になります。
このメソッドは2つの引数を取ります。1つ目のDOMNode $nodeは、インポートしたい元のノードを指定します。2つ目のbool $deepはオプションで、インポートするノードの子孫(子ノードやそのさらに子ノード)も一緒にインポートするかどうかを決定します。trueを指定するとノードとそのすべての子孫が、falseを指定するとノード自身のみがインポートされます。
メソッドは、インポート先のドキュメントに所属する新しいDom\Nodeオブジェクトを戻り値として返します。この戻り値は、元のノードとは異なる新しいノードであり、インポート先のドキュメントに属しています。
サンプルコードでは、まず2つのDom\XMLDocumentを作成し、一方のドキュメントからitemノードを選択します。次に、importNodeメソッドを使ってこのitemノードをもう一方のドキュメントにコピーし、trueを指定することで子孫ノード(テキストノード)も同時にインポートしています。importNodeメソッドはノードをコピーするだけで、自動的にドキュメントへ追加はしないため、最後にappendChildメソッドを使ってインポートしたノードをターゲットドキュメントのルートノードの下に追加しています。これにより、異なるドキュメントから取得したXML要素を現在のドキュメントに組み込むことが可能になります。
Dom\XMLDocument::importNodeは、別のXMLドキュメントに属するノードを、現在のドキュメントで使えるように「コピー」し、そのノードの所有権を現在のドキュメントに移すメソッドです。元のドキュメントのノードは変更されません。
初心者が特に注意すべき点は、importNodeはノードをコピーするだけで、自動的にドキュメントへ「追加」するわけではないことです。コピーされたノードは、appendChildなどのメソッドを使って、明示的にドキュメント内の適切な場所に追加する必要があります。
第二引数$deepをtrueにすると、ノードとそのすべての子孫ノードが一緒にコピーされますが、falseの場合はノード自身のみがコピーされます。この違いを理解し、目的に応じて正しく指定することが重要です。異なるドキュメント間でノードを直接操作しようとするとエラーとなるため、importNodeを使ってノードの所有権を移動させてから操作することが、安全で正しい利用に繋がります。
PHP DOM importNodeでXMLノードをインポートする
1<?php 2 3// XML ドキュメントを新規に作成します。 4$dom = new DomDocument('1.0', 'UTF-8'); 5 6// ルート要素を作成します。 7$root = $dom->createElement('root'); 8$dom->appendChild($root); 9 10// インポートするノードを持つ別のXMLドキュメントを作成します。 11$domImport = new DomDocument('1.0', 'UTF-8'); 12$domImport->loadXML('<item id="1"><name>Example</name></item>'); 13 14// インポートするノードを取得します。 15$nodeToImport = $domImport->documentElement; 16 17// ノードをインポートします。deep = true は子ノードもコピーします。 18$importedNode = $dom->importNode($nodeToImport, true); 19 20// インポートされたノードを新しいドキュメントに追加します。 21$root->appendChild($importedNode); 22 23// 結果を表示します。 24echo $dom->saveXML();
このサンプルコードは、PHPのDomDocumentクラスのimportNodeメソッドの使い方を示しています。importNodeメソッドは、別のXMLドキュメントからノードを現在のドキュメントにコピーするために使用されます。
まず、新しいXMLドキュメント ($dom) を作成し、ルート要素を追加します。次に、インポート元のXMLドキュメント ($domImport) を作成し、loadXMLメソッドでXML文字列を読み込みます。
$domImport->documentElementでインポートしたいノード(この例では<item>要素)を取得し、$dom->importNode($nodeToImport, true) を実行します。importNodeメソッドは、第一引数にインポートするノード、第二引数にdeepフラグを受け取ります。deepフラグがtrueの場合、指定されたノードだけでなく、そのすべての子ノードもコピーされます。falseの場合は、ノード自身のみがコピーされます。
importNodeメソッドは、インポートされたノードの新しいインスタンスを返します。この例では、$importedNodeにそのインスタンスが格納されます。最後に、$root->appendChild($importedNode)で、インポートされたノードを新しいドキュメントのルート要素の子要素として追加します。
$dom->saveXML()で、作成されたXMLドキュメントを文字列として出力し、結果を確認できます。このコードを実行すると、元のドキュメントにインポートされたノードが追加されたXMLが出力されます。このメソッドを使うことで、異なるXMLドキュメント間でノードを安全にコピーし、操作することが可能になります。
DomDocument::importNodeメソッドは、異なるXMLドキュメント間でノードをコピーする際に使用します。第一引数にはインポート元のノードを指定し、第二引数$deepは、ノードの子要素もまとめてコピーするかどうかを決定します。$deep = trueを指定すると、子要素も再帰的にコピーされます。
注意点として、インポートされたノードは元のドキュメントとは異なるノードオブジェクトとして扱われるため、元のノードを変更してもインポートされたノードには影響しません。また、importNodeはノードをコピーするだけで、ドキュメントに追加するわけではないため、appendChildなどのメソッドを使って明示的にドキュメントに追加する必要があります。インポート元のノードが存在しない場合や、不正な形式のノードをインポートしようとするとエラーが発生する可能性があります。