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

【PHP8.x】Dom\Text::C14N()メソッドの使い方

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

作成日: 更新日:

基本的な使い方

C14Nメソッドは、DOM(Document Object Model)のTextノードを、Canonical XML(C14N)形式でシリアライズ(直列化)するメソッドです。Textノードは、XMLドキュメント内のテキストコンテンツを表します。C14Nは、XMLドキュメントを特定のルールに従って標準化された形式に変換するプロセスであり、デジタル署名やデータの一意性検証において重要な役割を果たします。

このメソッドを使用することで、Textノードの内容を、プラットフォームや環境に依存しない一貫した形式で表現できます。C14Nメソッドは、Textノードが属するドキュメントコンテキストを考慮し、必要な名前空間宣言や属性などを適切に処理します。

C14Nメソッドを使用する主な目的は、異なるシステム間でXMLデータを交換する際に、データの整合性を保証することです。XMLドキュメントのわずかな違い(例えば、属性の順序や空白の有無)が、アプリケーションの動作に影響を与える可能性がある場合に、C14Nを使用してドキュメントを正規化することで、これらの問題を回避できます。

Dom\TextクラスのC14Nメソッドは、TextノードのコンテンツをC14N形式の文字列として返します。必要に応じて、出力のカスタマイズやエラー処理を行うためのオプション引数も提供される場合があります。具体的な使用方法や引数については、PHPの公式ドキュメントを参照してください。システムエンジニアは、XMLデータを扱うシステムを開発・運用する際に、C14Nの概念とこのメソッドの利用を理解しておくことが重要です。

構文(syntax)

1public Dom\Text::C14N( ?string $exclusive = null, ?bool $withComments = null, ?array $nodes = null, ?string $namespacePrefix = null ): bool

引数(parameters)

bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null

  • bool $exclusive = false: trueの場合、ノードの開始タグと終了タグのみを出力します。
  • bool $withComments = false: trueの場合、コメントノードも出力します。
  • ?array $xpath = null: 指定されたXPath式に一致するノードのみを対象とします。
  • ?array $nsPrefixes = null: 指定された名前空間プレフィックスのみを出力に含めます。

戻り値(return)

string|false

XML/HTML文書のテキストノードを正規化された形式の文字列として返します。正規化に失敗した場合は false を返します。

サンプルコード

PHP DOM\Text::C14NでXMLテキスト正規化

1<?php
2
3/**
4 * Dom\Text::C14N メソッドの使用例。
5 * XMLテキストノードの正規化された形式を取得します。
6 *
7 * C14N (Canonicalization) とは、XML文書のさまざまな表現を単一の標準形式に変換するプロセスです。
8 * これにより、XML文書の内容が同一であるかを比較する際に役立ちます。
9 * Dom\Text::C14N メソッドは、指定されたテキストノードの正規化された形式を返します。
10 *
11 * 注: 通常、C14NはXMLドキュメント全体や特定の要素に対して適用されます。
12 * テキストノード単体に対して適用する場合、そのテキスト内容がそのまま返されることが多いです。
13 * リファレンス情報にある引数 ($xpath, $nsPrefixes) は、通常 DOMDocument や DOMElement の C14N メソッドで
14 * 使用され、Dom\Text クラスの C14N メソッドでは一般的なユースケースが少ないため、
15 * ここではそれらを省略し、基本的な使用法に焦点を当てます。引数を省略した場合、デフォルト値 (null) が使用されます。
16 */
17function demonstrateDomTextC14N(): void
18{
19    // サンプルXML文字列
20    $xmlString = <<<XML
21<root xmlns="http://example.com/ns" xmlns:pref="http://example.com/pref">
22    <element attr="value &amp; test">
23        Hello
24        <!-- This is a comment -->
25        World!
26    </element>
27    <another>Simple Text</another>
28</root>
29XML;
30
31    // DOMDocument オブジェクトを作成し、XMLをロード
32    $dom = new DOMDocument();
33    $dom->loadXML($xmlString);
34    // 空白ノードを無視することで、目的のテキストノードにアクセスしやすくする
35    $dom->preserveWhiteSpace = false;
36
37    // <element> 要素を取得
38    $element = $dom->getElementsByTagName('element')->item(0);
39
40    if (!$element) {
41        echo "エラー: XML内に 'element' タグが見つかりませんでした。\n";
42        return;
43    }
44
45    // <element> 要素の子ノードを走査し、Dom\Text ノードを探す
46    $textNode = null;
47    foreach ($element->childNodes as $node) {
48        // PHP 8 では Dom\Text を使用。DOMText と同じです。
49        if ($node instanceof Dom\Text) {
50            $textNode = $node;
51            break; // 最初のテキストノードが見つかったら終了
52        }
53    }
54
55    if (!$textNode) {
56        echo "エラー: 'element' 内にテキストノードが見つかりませんでした。\n";
57        return;
58    }
59
60    echo "--- 元のテキストノードの値 ---\n";
61    // テキストノードの値から改行や余分な空白を除去して表示
62    echo "'" . trim($textNode->nodeValue) . "'\n\n";
63
64    // 1. デフォルトオプション (非排他的, コメントなし) で C14N を実行
65    // テキストノードの場合、通常は元のテキスト値がそのまま返されます。
66    $c14nDefault = $textNode->C14N();
67    if ($c14nDefault !== false) {
68        echo "--- C14N 結果 (デフォルトオプション: exclusive=false, withComments=false) ---\n";
69        echo "'" . $c14nDefault . "'\n\n";
70    } else {
71        echo "C14N がデフォルトオプションで失敗しました。\n\n";
72    }
73
74    // 2. コメントを含めるオプション (withComments = true) で C14N を実行
75    // テキストノード自体はコメントを持たないため、このオプションは結果に影響を与えません。
76    $c14nWithComments = $textNode->C14N(false, true);
77    if ($c14nWithComments !== false) {
78        echo "--- C14N 結果 (withComments=true) ---\n";
79        echo "'" . $c14nWithComments . "'\n\n";
80    } else {
81        echo "C14N が withComments=true オプションで失敗しました。\n\n";
82    }
83
84    // 3. 排他的正規化オプション (exclusive = true) で C14N を実行
85    // テキストノード単体では、このオプションも通常は結果に影響を与えません。
86    // 排他的正規化は、通常は要素やドキュメントレベルで名前空間の扱いを制御する際に重要になります。
87    $c14nExclusive = $textNode->C14N(true, false);
88    if ($c14nExclusive !== false) {
89        echo "--- C14N 結果 (exclusive=true) ---\n";
90        echo "'" . $c14nExclusive . "'\n\n";
91    } else {
92        echo "C14N が exclusive=true オプションで失敗しました。\n\n";
93    }
94}
95
96// 関数を実行
97demonstrateDomTextC14N();
98

PHP 8のDom\Text::C14Nメソッドは、XMLのテキストノードを正規化された形式に変換します。C14N(Canonicalization)とは、XML文書の表記揺れを吸収し、内容が同一であるかを比較できるように、標準的な形式に整えるプロセスです。このサンプルコードでは、XML文字列からDOMDocumentを生成し、特定の要素内のテキストノードを抽出して、そのテキストノードに対してC14Nメソッドを適用しています。

C14Nメソッドは、引数$exclusiveで排他的正規化の有無、$withCommentsでコメントを含めるかどうかを指定できます。また、$xpathで正規化対象をXPathで指定したり、$nsPrefixesで名前空間プレフィックスを指定したりすることも可能ですが、Dom\TextクラスのC14Nではこれらの引数が影響することは稀です。メソッドの戻り値は、正規化されたテキスト内容の文字列ですが、処理に失敗した場合はfalseを返します。

テキストノード単体に対するC14Nは、多くの場合、元のテキスト値がそのまま返される傾向にあります。これは、C14Nが主に要素やドキュメント全体における名前空間宣言や属性の表現方法、空白文字の扱いなどを標準化する際に、より顕著な効果を発揮するためです。サンプルコードでは、デフォルトオプション、コメントを含めるオプション、排他的正規化オプションのそれぞれの結果を表示し、その挙動を確認しています。

このサンプルコードで扱っているDom\Text::C14Nメソッドは、XML文書の異なる表現を単一の標準形式に変換する正規化(C14N)プロセスを行います。ただし、このメソッドは通常、XMLドキュメント全体や特定の要素に対して適用されることでその真価を発揮します。テキストノード単体にC14Nを適用する場合、多くはそのテキスト内容がそのまま返されることが一般的です。そのため、引数$exclusive$withCommentsを設定しても、テキストノードのC14N結果に大きな変化が見られない点にご注意ください。特に$xpath$nsPrefixesといった引数は、テキストノードのC14Nではほとんど利用されません。メソッドは成功時に正規化された文字列を、失敗時にはfalseを返すため、常にその戻り値をチェックし、エラーハンドリングを行うことが重要です。PHP 8以降ではDOMTextクラスの代わりにDom\Textクラスを使用しますが、機能は同等です。

関連コンテンツ

関連プログラミング言語