【PHP8.x】Dom\ProcessingInstruction::replaceWith()メソッドの使い方
replaceWithメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
replaceWithメソッドは、DOMツリー内の処理命令ノード(ProcessingInstruction)を、指定した一つ以上の新しいノードで置き換える操作を実行するメソッドです。このメソッドを呼び出すと、呼び出し元のDom\ProcessingInstructionオブジェクトは、その親ノードが持つ子ノードのリストから削除されます。そして、そのノードがあった位置に、引数として渡されたノードが順番に挿入されます。引数には、置き換え後に追加したいノードをDOMNodeオブジェクトまたは文字列として、カンマ区切りで複数指定することが可能です。引数に文字列が指定された場合、その文字列は自動的にDom\Textノードとして扱われ、DOMツリーに挿入されます。このメソッドはDOMツリーを直接変更する操作を行うため、返り値はありません。もし、ノードの階層関係が不正であるなど、置き換え処理が実行できない状況が発生した場合には、DOMExceptionがスローされることがあります。これにより、既存の処理命令を動的に他の要素やテキストに差し替えるといった操作を簡単に行うことができます。
構文(syntax)
1<?php 2// $processingInstruction は Dom\ProcessingInstruction オブジェクト 3// $node は Dom\Node オブジェクト 4$processingInstruction->replaceWith($node, "テキスト文字列", /*, ... */);
引数(parameters)
Dom\Node|string ...$nodes
- Dom\Node|string ...$nodes: 置換する対象となるノード、またはノードの配列、もしくは文字列を指定します
戻り値(return)
void
このメソッドは、呼び出し元の Dom\ProcessingInstruction オブジェクトを、指定されたノードまたはノードの配列で置き換えます。置換されたノードは、元のノードがあった場所と同じ位置に挿入されます。戻り値はありません。
サンプルコード
PHP DOM ProcessingInstruction::replaceWith を使う
1<?php 2 3declare(strict_types=1); 4 5/** 6 * Dom\ProcessingInstruction::replaceWith() の使用方法を示すサンプルクラスです。 7 * 8 * XMLドキュメント内の特定の処理命令 (Processing Instruction) を、 9 * 新しい要素ノードとテキスト文字列に置き換えます。 10 */ 11class ProcessingInstructionReplacer 12{ 13 /** 14 * メインの処理を実行します。 15 */ 16 public function run(): void 17 { 18 // 操作対象となるXML文字列を定義します。 19 // `<?php-directive ...?>` が処理命令ノードです。 20 $xmlString = <<<XML 21<?xml version="1.0" encoding="UTF-8"?> 22<root> 23 <item>コンテンツ1</item> 24 <?php-directive enable-feature="x"?> 25 <item>コンテンツ2</item> 26</root> 27XML; 28 29 // DOMDocumentオブジェクトを生成し、XMLを読み込みます。 30 $dom = new \DOMDocument(); 31 $dom->preserveWhiteSpace = false; 32 $dom->formatOutput = true; // 出力を整形して見やすくします。 33 $dom->loadXML($xmlString); 34 35 echo "--- 置き換え前のXML ---\n"; 36 echo $dom->saveXML(); 37 echo "\n"; 38 39 // 置き換え対象の処理命令ノードを取得します。 40 // XPathを使って `php-directive` というターゲットを持つ処理命令を検索します。 41 $xpath = new \DOMXPath($dom); 42 $piNodes = $xpath->query('//processing-instruction("php-directive")'); 43 44 if ($piNodes->length > 0) { 45 /** @var Dom\ProcessingInstruction $piNode */ 46 $piNode = $piNodes->item(0); 47 48 // 置き換え用の新しいノード(要素とコメント)と文字列を準備します。 49 $newElement = $dom->createElement('new-element', 'この要素に置き換えられました。'); 50 $newComment = $dom->createComment('処理命令は削除されました'); 51 $newString = "\n <!-- 文字列も直接追加できます -->\n "; 52 53 // replaceWith() を使って処理命令を複数のノードと文字列に置き換えます。 54 // 引数は可変長で、複数のノードや文字列を渡すことができます。 55 $piNode->replaceWith($newComment, $newString, $newElement); 56 57 echo "--- 置き換え後のXML ---\n"; 58 echo $dom->saveXML(); 59 } 60 } 61} 62 63// クラスのインスタンスを生成して実行します。 64(new ProcessingInstructionReplacer())->run();
Dom\ProcessingInstruction::replaceWith()は、XMLドキュメント内の特定の処理命令ノードを、一つまたは複数の新しいノードや文字列で置き換えるためのメソッドです。処理命令ノードとは、<?target ...?>という形式で記述される特別な指示を指します。
サンプルコードでは、まずXML文字列をDOMDocumentオブジェクトとして読み込み、XPathを利用して<?php-directive ...?>という処理命令ノードを特定しています。次に、置き換え先として使用する新しい要素ノード、コメントノード、そして改行などを含む文字列をそれぞれ準備します。
このreplaceWith()メソッドの引数には、置き換えたいDom\Nodeオブジェクトや文字列を、カンマで区切って複数指定できます。このように引数をいくつでも渡せるのが特徴です。メソッドが実行されると、呼び出し元である処理命令ノードがDOMツリーから削除され、その位置に引数で指定したノードや文字列が順番に挿入されます。
このメソッドには戻り値はなく(void)、操作対象のドキュメントが直接変更されます。最終的に、元の処理命令があった場所に、指定したコメント、文字列、新しい要素が挿入されたXMLが出力されていることが確認できます。
replaceWith()メソッドを呼び出すと、元のノードはDOMツリーから完全に削除されます。そのため、置き換え後に元のノードを再度使おうとするとエラーになる点に注意してください。引数にはノードオブジェクトだけでなく文字列も渡せますが、文字列にXMLの特殊文字(例: < や &)が含まれていると、XML構造が壊れる恐れがあります。安全にテキストを追加するには$dom->createTextNode()でテキストノードを生成してから渡すのが確実です。また、引数として渡す新しいノードは、必ず操作対象と同じDOMDocumentオブジェクト(この例では$dom)で作成する必要があります。このメソッドは複数の引数を指定でき、渡した順にノードが挿入されていきます。