【PHP8.x】C14Nメソッドの使い方

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

作成日: 更新日:

基本的な使い方

C14Nメソッドは、DOMDocumentFragmentオブジェクトに含まれるXMLノードの内容を、W3C勧告のXML正規化(Canonical XML、略称C14N)の規則に従って文字列として出力するメソッドです。この正規化は、XML文書の物理的な表現の違い(例えば属性の順序や名前空間宣言の書き方など)を吸収し、論理的に同一のXML内容が常に同じバイト列となるように変換するプロセスを指します。

主に、XMLデジタル署名において、署名の対象となるXML文書の内容が改ざんされていないことを検証する際に利用されます。DOMDocumentFragmentは、XML文書全体ではなく、その一部のノードの集まりを表しますが、このメソッドを使用することで、そのフラグメント部分のみを正規化できます。

このメソッドは、排他的正規化を適用するかどうか、コメントノードを含めるかどうか、正規化の対象とするノードをXPath式で指定するかどうかなど、いくつかのオプション引数を受け入れます。これらのオプションを適切に指定することで、正規化の挙動を細かく制御することが可能です。具体的には、exclusive引数で排他的正規化の有効/無効を、with_comments引数でコメントを含めるか否かを設定でき、xpathns_prefixesの引数を使用することで、特定のノードセットのみを対象とした正規化を行うことができます。成功した場合は正規化されたXML文字列を返し、失敗した場合はfalseを返します。

構文(syntax)

1<?php
2$fragment = new DOMDocumentFragment();
3$canonicalizedString = $fragment->C14N();
4?>

引数(parameters)

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

  • bool $exclusive = false: 排他的な正規化を行うかどうかを指定します。true に設定すると、要素の全祖先ノードではなく、指定されたノードのみを正規化します。
  • bool $withComments = false: コメントノードを正規化に含めるかどうかを指定します。
  • ?array $xpath = null: 正規化の対象となるノードをXPath式で指定します。
  • ?array $nsPrefixes = null: 正規化で考慮する名前空間プレフィックスの配列を指定します。

戻り値(return)

string|false

DOMDocumentFragment::c14nメソッドは、XML文書の正規化された文字列表現を返します。正規化に失敗した場合はfalseを返します。

サンプルコード

PHP DOMDocumentFragment C14N変換

1<?php
2
3/**
4 * DOMDocumentFragment を使用して XML ドキュメントを C14N (Canonical XML) 形式に変換する例
5 *
6 * @return void
7 */
8function c14nExample(): void
9{
10    // DOMDocument の作成
11    $dom = new DOMDocument('1.0', 'UTF-8');
12
13    // ルート要素の作成
14    $root = $dom->createElement('root');
15    $dom->appendChild($root);
16
17    // フラグメントの作成
18    $fragment = $dom->createDocumentFragment();
19    $fragment->appendXML('<child attribute="value">Text</child>');
20    $root->appendChild($fragment);
21
22    // C14N 形式に変換
23    $c14n = $dom->documentElement->C14N(
24        exclusive: true,      // 排他的 C14N を使用するかどうか
25        withComments: false,     // コメントを含めるかどうか
26        xpath: null,           // XPath 式の配列
27        nsPrefixes: null         // 名前空間プレフィックスの配列
28    );
29
30    // 結果の出力
31    if ($c14n !== false) {
32        echo $c14n . PHP_EOL;
33    } else {
34        echo "C14N transformation failed." . PHP_EOL;
35    }
36}
37
38// 関数の実行
39c14nExample();

このPHPのサンプルコードは、DOMDocumentFragmentクラスのC14Nメソッドを使用して、XMLドキュメントをCanonical XML (C14N)形式に変換する方法を示しています。C14Nは、XMLドキュメントを標準化された形式に変換することで、内容が論理的に同一であるにも関わらず、字面が異なるXMLドキュメントを比較できるようにします。

まず、DOMDocumentオブジェクトを作成し、ルート要素を追加します。次に、createDocumentFragment()メソッドでドキュメントフラグメントを作成し、XML文字列をappendXML()で追加します。このフラグメントをルート要素の子要素として追加します。

C14Nメソッドは、以下の引数を持ちます。$exclusiveは排他的C14Nを使用するかどうかを指定します。$withCommentsは結果にコメントを含めるかどうかを指定します。$xpathは処理対象のノードを選択するためのXPath式の配列を指定します。$nsPrefixesは名前空間プレフィックスの配列を指定します。これらの引数を使用することで、C14N変換の動作を細かく制御できます。

C14Nメソッドは、変換されたXML文字列を返します。変換に失敗した場合はfalseを返します。サンプルコードでは、変換結果がfalseでないことを確認し、変換されたXML文字列を出力しています。exclusive引数をtrueに設定することで、より厳密な標準化が行われます。

DOMDocumentFragment::C14Nメソッドは、XMLの一部を標準化された形式(Canonical XML)に変換します。初心者の方は、以下の点に注意してください。

引数のexclusiveは、排他的C14Nを使用するかどうかを指定します。trueにすると、より厳密な標準化が行われます。xpath引数は、標準化するノードをXPathで指定する場合に使用します。通常はnullで問題ありません。nsPrefixesは、名前空間プレフィックスを限定する場合に使用しますが、通常はnullで構いません。

戻り値がfalseの場合、変換に失敗しています。エラー処理を追加し、原因を特定できるようにしておくと良いでしょう。C14NはXML署名などで利用される技術であり、セキュリティに関わる処理で使用されることが多いため、パラメータの意味を理解して適切に設定することが重要です。

PHP DOMDocumentFragment C14N 1.1 出力

1<?php
2
3/**
4 * DOMDocumentFragment を使用して、C14N (Canonical XML) 形式で XML を出力するサンプル
5 * C14N 1.1 形式で XML を出力します。
6 */
7
8function generateC14N11Example(): void
9{
10    // DOMDocument を作成
11    $dom = new DOMDocument('1.0', 'UTF-8');
12
13    // ルート要素を作成
14    $root = $dom->createElement('root');
15    $dom->appendChild($root);
16
17    // フラグメントを作成
18    $fragment = $dom->createDocumentFragment();
19
20    // フラグメントに要素を追加
21    $element = $dom->createElement('element', 'This is an example.');
22    $fragment->appendChild($element);
23
24    // フラグメントをルート要素に追加
25    $root->appendChild($fragment);
26
27    // C14N 1.1 形式で XML を出力
28    $c14nXml = $dom->documentElement->C14N(true, false);
29
30    // 結果を表示
31    if ($c14nXml !== false) {
32        echo $c14nXml . PHP_EOL;
33    } else {
34        echo "C14N failed." . PHP_EOL;
35    }
36}
37
38generateC14N11Example();
39

このサンプルコードは、PHPのDOMDocumentFragmentクラスでC14Nメソッドを使用して、XMLドキュメントをCanonical XML形式(C14N 1.1)で出力する方法を示しています。C14Nは、XMLドキュメントを正規化するための標準的な方法で、XMLの構造は変えずに、属性の順序や空白などの違いを正規化し、同じ内容のXMLを常に同じ形式で表現できるようにします。

まず、DOMDocumentオブジェクトを作成し、XMLドキュメントのルート要素を作成します。次に、createDocumentFragmentメソッドでドキュメントフラグメントを作成し、createElementメソッドで要素を作成してフラグメントに追加します。作成したフラグメントをルート要素に追加することで、XMLドキュメントに要素を組み込んでいます。

C14Nメソッドは、XMLドキュメントをC14N形式で文字列として返します。引数$exclusiveは排他的なC14N形式を使用するかどうかを指定します。trueに設定するとC14N 1.1形式になります。$withCommentsはコメントを含めるかどうかを指定します。$xpathは正規化するノードをXPath式で指定します。$nsPrefixesは名前空間プレフィックスの配列を指定します。このサンプルでは、$exclusivetrueに設定し、C14N 1.1形式でXMLを出力しています。

C14Nメソッドが成功すると、正規化されたXML文字列が返されます。失敗した場合はfalseが返されます。サンプルコードでは、返り値がfalseでないことを確認し、成功した場合のみ結果を出力します。

DOMDocumentFragment::C14Nメソッドは、XMLの一部(この例ではフラグメント)を標準化された形式で出力します。引数$exclusive = trueは、C14N 1.1形式を指定します。$withComments = falseはコメントを含めない設定です。$xpath$nsPrefixesは、より細かい制御に使いますが、ここでは省略しています。

XML処理では文字コードに注意が必要です。DOMDocumentのコンストラクタでUTF-8を指定していますが、スクリプト自体の文字コードもUTF-8であることを確認してください。

C14N処理が失敗するとfalseが返るため、必ずエラーハンドリングを行いましょう。C14Nメソッドは、XML構造や設定によっては期待どおりの結果にならない場合があるので、出力結果を検証することが重要です。

関連コンテンツ

関連プログラミング言語