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

【PHP8.x】DOMProcessingInstruction::normalize()メソッドの使い方

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

作成日: 更新日:

基本的な使い方

normalizeメソッドは、ノードとその配下にあるすべての子孫ノード(サブツリー)を正規化するメソッドです。正規化とは、DOMツリーの構造を定義された形式に整形・整理する処理を指します。このメソッドが行う主な処理は、隣接するテキストノード(DOMText)を一つのノードに結合することと、内容が空のテキストノードを削除することです。例えば、DOM操作の過程で「こんにちは」と「世界」というテキストが二つの隣接するノードに分割されてしまった場合、normalizeメソッドを呼び出すことで「こんにちは世界」という一つのテキストノードに統合されます。この処理により、意図せず断片化したDOMツリーの構造が簡潔になり、後続のノード操作やデータ抽出をより確実かつ容易に行えるようになります。DOMProcessingInstructionクラスはDOMNodeクラスを継承しているため、このメソッドが利用可能です。ドキュメントの構造をクリーンな状態に保ちたい場合に役立ちます。

構文(syntax)

1<?php
2
3$dom = new DOMDocument();
4
5$processing_instruction = $dom->createProcessingInstruction(
6    'xml-stylesheet',
7    'type="text/css" href="style.css"'
8);
9
10// DOMProcessingInstruction オブジェクトとその子孫を「正規化」します。
11$processing_instruction->normalize();
12
13?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP DOMProcessingInstruction::normalize() の挙動確認

1<?php
2
3/**
4 * DOMProcessingInstruction::normalize() の動作を確認するサンプルクラスです。
5 *
6 * このメソッドは、DOMツリーの正規化を行いますが、
7 * DOMProcessingInstruction ノード自体は子ノードを持たないため、
8 * このノードに対して呼び出しても目に見える変化はありません。
9 * このサンプルでは、その挙動をコードで示します。
10 */
11class ProcessingInstructionNormalizer
12{
13    /**
14     * サンプルコードを実行します。
15     */
16    public function run(): void
17    {
18        // 1. DOMDocumentオブジェクトを生成
19        $dom = new DOMDocument('1.0', 'UTF-8');
20        // 出力されるXMLを整形して見やすくする
21        $dom->formatOutput = true;
22
23        // 2. ルート要素 <document> を作成して追加
24        $root = $dom->createElement('document');
25        $dom->appendChild($root);
26
27        // 3. 処理命令 (Processing Instruction) ノードを作成して追加
28        // これはXML文書内でアプリケーションに情報を渡すための <?target data?> という形式のノードです。
29        $pi = $dom->createProcessingInstruction(
30            'xml-stylesheet',
31            'type="text/css" href="style.css"'
32        );
33        $root->appendChild($pi);
34
35        echo "--- normalize() 呼び出し前のXML ---" . PHP_EOL;
36        echo $dom->saveXML();
37        echo PHP_EOL;
38
39        // 4. DOMProcessingInstruction オブジェクトに対して normalize() を呼び出す
40        //
41        // DOMNode::normalize() は、主に隣接するテキストノードを結合するために使用されます。
42        // しかし、DOMProcessingInstruction ノードは子ノードを持つことができないため、
43        // このメソッドを呼び出しても、このノード自体やドキュメント構造に変化は起こりません。
44        $pi->normalize();
45
46        echo "--- normalize() 呼び出し後のXML (変化なし) ---" . PHP_EOL;
47        echo $dom->saveXML();
48    }
49}
50
51// クラスのインスタンスを作成して実行
52$normalizer = new ProcessingInstructionNormalizer();
53$normalizer->run();

PHPのDOMProcessingInstruction::normalize()メソッドは、DOMツリーのノードを正規化するためのものです。このメソッドは親クラスであるDOMNodeから継承された機能で、引数はなく、戻り値もありません。

このサンプルコードでは、まずDOMDocumentオブジェクトを作成し、<?xml-stylesheet ... ?>という形式の処理命令ノード(Processing Instruction Node)をXMLドキュメントに追加します。処理命令ノードは、XML文書内で特定のアプリケーションに指示を伝えるために使用されるものです。

次に、この作成した処理命令ノードオブジェクトに対してnormalize()メソッドを呼び出しています。normalize()メソッドの主な役割は、隣り合ったテキストノードなどを一つに結合することですが、処理命令ノードはXMLの仕様上、子ノードを持つことができません。そのため、結合対象となるノードが存在せず、このメソッドを呼び出してもドキュメントの構造に目に見える変化は起こりません。

このコードは、normalize()呼び出しの前後でXMLの内容が全く変わらないことを出力で示すことにより、DOMProcessingInstructionノードに対するnormalize()メソッドの具体的な挙動を実証しています。

DOMProcessingInstruction::normalize()メソッドは、XMLの処理命令ノード(<?...?>)に対して呼び出しても、ドキュメントの構造に変化を与えません。このメソッドの主な役割は、隣接するテキストノードを一つにまとめることですが、処理命令ノードはXMLの仕様上、子ノードを持つことができません。そのため、結合対象となるテキストノードが存在せず、結果として何も起こりません。エラーにはなりませんが、normalize()という名前から何らかの整形処理を期待しないよう注意が必要です。このメソッドが効果を発揮するのは、子としてテキストが分割されうるDOMElementなどに対して使用する場合です。

PHP DOMnormalize でテキストノードを正規化する

1<?php
2
3/**
4 * DOMProcessingInstruction を含むドキュメントで normalize() の効果を確認します。
5 *
6 * DOMNode::normalize() は、ノードとその配下にある隣接したテキストノードを一つに統合し、
7 * 空のテキストノードを削除します。
8 * DOMProcessingInstruction クラスも DOMNode を継承しているためこのメソッドを持ちますが、
9 * このメソッドの主な効果は、テキストノードを含む親要素で呼び出されたときに現れます。
10 *
11 * このコードは、PHPに標準でバンドルされている dom 拡張機能を使用します。
12 * キーワードにある intl 拡張機能の Normalizer クラスとは異なります。
13 */
14function demonstrateDomProcessingInstructionNormalize(): void
15{
16    // 処理命令 (DOMProcessingInstruction) を含むXML文字列を定義
17    $xmlString = <<<XML
18<?xml version="1.0" encoding="UTF-8"?>
19<?php-app version="1.0"?>
20<data>
21    <message></message>
22</data>
23XML;
24
25    // DOMDocumentオブジェクトを作成してXMLを読み込む
26    $dom = new DOMDocument();
27    $dom->preserveWhiteSpace = false;
28    $dom->formatOutput = true;
29    $dom->loadXML($xmlString);
30
31    // <message>要素のノードを取得
32    $messageNode = $dom->getElementsByTagName('message')->item(0);
33
34    // 正規化の効果を示すために、意図的に複数の隣接するテキストノードを追加
35    $messageNode->appendChild($dom->createTextNode('First part. '));
36    $messageNode->appendChild($dom->createTextNode('Second part.'));
37    
38    // 正規化前のXMLを出力
39    // この時点では、<message>要素は2つの子テキストノードを持つ
40    echo "--- Before normalize() ---\n";
41    echo $dom->saveXML();
42
43    // ドキュメントのルート要素を取得し、正規化を実行
44    // これにより、配下にある隣接したテキストノードが1つにマージされる
45    $dom->documentElement->normalize();
46
47    // 正規化後のXMLを出力
48    // <message>要素の子テキストノードが1つに統合されていることを確認できる
49    echo "\n--- After normalize() ---\n";
50    echo $dom->saveXML();
51}
52
53// 関数を実行
54demonstrateDomProcessingInstructionNormalize();

DOMProcessingInstruction::normalize()は、XMLドキュメントの構造を整理するためのメソッドです。これは、親クラスであるDOMNodeから継承された機能で、主な役割は、隣接している複数のテキストノードを一つに統合し、空のテキストノードを削除することです。これにより、ドキュメントの構造が簡潔になり、処理しやすくなります。

サンプルコードでは、まず処理命令を含むXML文書を作成し、<message>要素内に意図的に2つのテキストノード「First part. 」と「Second part.」を隣接させて追加します。normalize()メソッドを呼び出す前は、これらは内部的に2つの別々のノードとして扱われます。ドキュメント全体に対してnormalize()を実行すると、これらの隣接するテキストノードが1つのテキストノードに統合され、XMLの構造が最適化されます。

このメソッドは引数を取りません。また、戻り値もなく、呼び出したオブジェクト自体の内部状態を直接変更します。なお、この機能はPHPに標準で含まれるdom拡張機能の一部であり、Unicode文字列を扱うintl拡張機能のNormalizerクラスとは異なりますので、別途インストールは不要です。

このnormalize()メソッドは、呼び出したノードとその配下にある隣接したテキストノードを一つに結合し、空のテキストノードを削除する機能です。DOMProcessingInstructionクラスもこのメソッドを持ちますが、自身に子ノードがないため、このノードに直接呼び出しても目に見える変化はありません。サンプルコードのように、テキストノードを子に持つ親要素に対して呼び出すことで、その効果が発揮されます。また、この機能はPHP標準のdom拡張機能によるもので、文字列のUnicode正規化を行うintl拡張機能のNormalizerクラスとは全くの別物です。そのため、通常は追加のインストールは必要ありません。

関連コンテンツ

関連プログラミング言語

【PHP8.x】DOMProcessingInstruction::normalize()メソッドの使い方 | いっしー@Webエンジニア