【PHP8.x】Dom\ProcessingInstruction::normalize()メソッドの使い方
normalizeメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『normalizeメソッドは、ノードとその配下にある全てのサブツリーを正規化するメソッドです』
正規化とは、DOMツリーの構造を整理し、標準的な形式に整える処理を指します。具体的には、隣接して存在する複数のテキストノードを内容が連結された一つのノードに統合したり、内容が空のテキストノードを削除したりします。このメソッドは、XMLやHTMLドキュメントを解析または操作する前に、文書構造をよりシンプルで予測可能な状態にするために役立ちます。このメソッドは、全てのノードの基本となるDom\Nodeクラスから継承されたものです。しかし、Dom\ProcessingInstructionが表す処理命令ノードは、その仕様上、子ノードとしてテキストノードを持つことができません。そのため、Dom\ProcessingInstructionオブジェクトに対してこのメソッドを呼び出しても、対象となるテキストノードが存在しないため、実質的に何も処理は行われず、ノード自体に変更が加えられることはありません。主にDom\ElementやDom\Documentのような、子ノードを持つことができるノードに対して使用することで効果を発揮します。
構文(syntax)
1<?php 2 3// Dom\Document オブジェクトをインスタンス化します 4$document = new Dom\Document(); 5 6// Dom\ProcessingInstruction オブジェクトを生成します 7$pi = $document->createProcessingInstruction( 8 'xml-stylesheet', 9 'type="text/css" href="style.css"' 10); 11 12// ProcessingInstructionノードを正規化します。 13// このメソッドは値を返しません。 14$pi->normalize(); 15 16?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
void
このメソッドは、Processing Instructionノードの内部テキストを正規化します。正規化とは、連続する空白文字を1つの空白文字に置換し、テキストノードを結合する処理のことです。このメソッドは、DOMツリーの構造を変更しますが、戻り値はありません。
サンプルコード
PHP DOM正規化でテキストノードを結合する
1<?php 2 3/** 4 * Dom\ProcessingInstructionを含むDOMツリーでnormalize()メソッドの効果を確認するサンプルコード 5 * 6 * `normalize()` メソッドは、指定されたノードとそのサブツリー全体を正規化します。 7 * 具体的には、隣接するテキストノードを1つのノードにマージし、 8 * 空のテキストノードを削除します。 9 * このメソッドは `Dom\Node` クラスから継承されるため、 10 * `Dom\ProcessingInstruction` を含む多くのDOMノードで利用可能です。 11 */ 12function demonstrateDomNormalization(): void 13{ 14 // 1. DOMDocumentオブジェクトを作成 15 $dom = new DOMDocument('1.0', 'UTF-8'); 16 // 出力されるXMLを見やすくフォーマットする 17 $dom->formatOutput = true; 18 19 // 2. ルート要素 <root> を作成し、ドキュメントに追加 20 $root = $dom->createElement('root'); 21 $dom->appendChild($root); 22 23 // 3. 処理命令 (Processing Instruction) ノードを作成し、ルート要素に追加 24 // これは <?php-formatter-ignore?> のようなノードになります 25 $pi = $dom->createProcessingInstruction('php-formatter', 'ignore'); 26 $root->appendChild($pi); 27 28 // 4. 複数の隣接するテキストノードを持つ <content> 要素を作成 29 // これらは normalize() によって結合される対象です 30 $content = $dom->createElement('content'); 31 $content->appendChild($dom->createTextNode('隣接テキスト1')); 32 $content->appendChild($dom->createTextNode('と')); 33 $content->appendChild($dom->createTextNode('隣接テキスト2')); 34 $root->appendChild($content); 35 36 // 5. 正規化前のXMLを出力 37 echo "--- normalize() 実行前 ---" . PHP_EOL; 38 echo $dom->saveXML(); 39 echo PHP_EOL; 40 41 // 6. ルート要素に対して normalize() を実行 42 // これにより、<content> 要素内の3つのテキストノードが1つにマージされます 43 $dom->documentElement->normalize(); 44 45 // 7. 正規化後のXMLを出力 46 echo "--- normalize() 実行後 ---" . PHP_EOL; 47 echo $dom->saveXML(); 48} 49 50demonstrateDomNormalization();
このPHPサンプルコードは、XMLのDOMツリー構造を整理する normalize() メソッドの動作を実演するものです。normalize() は、指定したノードとその全ての子孫ノードを正規化します。主な役割は、隣接して存在する複数のテキストノードを一つのテキストノードに結合し、空のテキストノードを削除することです。これにより、XMLの構造がより簡潔で扱いやすくなります。
コードでは、まず<root>要素、処理命令ノード <?php-formatter ignore?>、そして<content>要素を持つDOMドキュメントを構築します。<content>要素内には、「隣接テキスト1」「と」「隣接テキスト2」という3つの別々のテキストノードを意図的に配置しています。
最初にnormalize()を呼び出す前のXMLを出力し、テキストノードが分割されている状態を確認します。次に、ドキュメントのルート要素に対してnormalize()メソッドを実行します。このメソッドは引数を取らず、戻り値もありません(void)。呼び出したノードの状態を直接変更します。実行後、再度XMLを出力すると、3つに分かれていたテキストノードが「隣接テキスト1と隣接テキスト2」という一つのノードに統合されていることがわかります。
このnormalize()メソッドは、Dom\ProcessingInstructionクラスが親クラスのDom\Nodeから継承している機能のため、要素ノードなど他の多くのDOMノードでも同様に利用できます。
normalize()メソッドは、指定したノードだけでなく、その配下にある全ての子孫ノードに対して効果を及ぼします。サンプルコードではルート要素で呼び出しているため、ドキュメント全体が正規化の対象です。このメソッドはDom\ProcessingInstructionに限らず、多くのDOMノードで使える共通の機能です。主な役割は、隣接するテキストノードを一つにまとめたり、空のテキストノードを削除したりすることです。この処理は元のDOMオブジェクトを直接変更し、新しい値を返しません。そのため、実行前の状態を残したい場合は、事前にオブジェクトを複製するなどの対応が必要です。