【PHP8.x】C14Nメソッドの使い方
C14Nメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
C14Nメソッドは、Dom\Documentクラスに属し、XML文書の正規化(Canonicalization)を実行するメソッドです。XML文書は、同じ内容であっても、空白文字の扱い方や属性の順序、名前空間の宣言方法など、様々な物理的な表現の違いを持つことがあります。このメソッドは、これらの見た目上の違いを吸収し、XML文書を標準的かつ統一された形式の文字列に変換します。これにより、論理的に同じ内容を持つXML文書であれば、物理的な表現が異なっていても、常に同じ正規化された文字列として扱えるようになります。
この機能は、特にXML署名やXML暗号化など、セキュリティが重要な場面で非常に役立ちます。例えば、XML署名においては、署名対象のXML文書がわずかに変更された場合でも、正規化によって常に同じ形式に変換されるため、署名の検証が正確に行われ、文書の改ざんを確実に検出できます。
C14Nメソッドは、排他的C14Nを使用するかどうか、コメントを含めるかどうか、あるいはXML文書全体ではなく特定のXPath式で指定されたノードセットのみを対象とするかなど、正規化の挙動を詳細に制御するためのオプション引数をサポートしています。メソッドが実行されると、正規化されたXML文書の文字列が戻り値として返されます。XML文書の信頼性や異なるシステム間での互換性を保証するために不可欠な機能の一つです。
構文(syntax)
1<?php 2$domDocument = new Dom\Document(); 3$domDocument->loadXML('<root><child attribute="value">text</child><!-- comment --></root>'); 4 5$canonicalizedXml = $domDocument->C14N( 6 exclusive: false, 7 with_comments: false, 8 xpath: null, 9 ns_prefixes: null 10);
引数(parameters)
bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null
- bool $exclusive: true を指定すると、正規化される要素のサブセットのみを対象にします。デフォルトは false です。
- bool $withComments: true を指定すると、コメントノードも正規化の対象に含めます。デフォルトは false です。
- ?array $xpath: 正規化する要素を XPath 式の配列で指定します。null の場合はドキュメント全体が対象です。
- ?array $nsPrefixes: 特定の名前空間プレフィックスのみを正規化の対象に含める場合に指定します。null の場合はすべて考慮されます。
戻り値(return)
string|false
このメソッドは、XML文書の標準的な表記形式(C14N)に正規化された文字列を返します。正規化に失敗した場合は false を返します。
サンプルコード
PHP DOM C14N による XML 正規化
1<?php 2 3// DomDocument を使用して XML ドキュメントを作成し、C14N を適用する例 4$dom = new DOMDocument('1.0', 'utf-8'); 5$dom->preserveWhiteSpace = false; 6$dom->formatOutput = true; 7 8// ルート要素を作成 9$root = $dom->createElement('root'); 10$dom->appendChild($root); 11 12// 子要素を作成 13$child1 = $dom->createElement('child1', 'テキスト1'); 14$root->appendChild($child1); 15 16$child2 = $dom->createElement('child2', 'テキスト2'); 17$root->appendChild($child2); 18 19// C14N を適用 20$c14n = $dom->C14N(); 21 22if ($c14n !== false) { 23 // C14N 適用後の XML を出力 24 echo $c14n . PHP_EOL; 25} else { 26 echo "C14N 適用に失敗しました。" . PHP_EOL; 27} 28 29// XPath を使用して特定のノードのみを C14N に適用する例 30$dom2 = new DOMDocument('1.0', 'utf-8'); 31$dom2->preserveWhiteSpace = false; 32$dom2->formatOutput = true; 33 34$root2 = $dom2->createElement('root'); 35$dom2->appendChild($root2); 36 37$child3 = $dom2->createElement('child3', 'テキスト3'); 38$root2->appendChild($child3); 39 40$child4 = $dom2->createElement('child4', 'テキスト4'); 41$root2->appendChild($child4); 42 43$xpath = new DOMXPath($dom2); 44$nodeList = $xpath->query('/root/child3'); 45 46$nodes = []; 47foreach ($nodeList as $node) { 48 $nodes[] = $node; 49} 50 51$c14n_exclusive = $dom2->C14N(true, false, $nodes); 52 53if ($c14n_exclusive !== false) { 54 echo $c14n_exclusive . PHP_EOL; 55} else { 56 echo "C14N 適用に失敗しました。" . PHP_EOL; 57} 58?>
PHP 8 の Dom\Document クラスにおける C14N メソッドは、XML ドキュメントを正規化する機能を提供します。XML の構造を標準化することで、異なるシステム間での相互運用性を高めたり、デジタル署名の信頼性を向上させたりすることが可能です。
C14N メソッドは、引数によって正規化の範囲や方法を調整できます。$exclusive は排他的な正規化を行うかどうかを指定するブール値で、true を指定すると、ドキュメント内の名前空間宣言をより厳密に処理します。$withComments は、コメントを含めるかどうかを指定するブール値です。$xpath は、正規化の対象とするノードを XPath 式で指定するための配列です。$nsPrefixes は、正規化に使用する名前空間プレフィックスの配列です。
サンプルコードでは、まず DOMDocument オブジェクトを作成し、XML ドキュメントの構造を定義しています。C14N() を引数なしで呼び出すと、ドキュメント全体が正規化されます。C14N(true, false, $nodes) のように引数を指定すると、XPath で選択された特定のノードのみを排他的に正規化できます。
C14N メソッドは、正規化された XML ドキュメントの文字列を返します。正規化に失敗した場合は false を返します。返り値が false でないことを確認することで、正規化が正常に完了したかどうかを判断できます。
DOMDocument::C14N() メソッドは、XMLドキュメントを標準化する際に使用します。引数 $exclusive は、排他的C14Nを適用するかどうかを指定します。$withComments は、XMLコメントを含めるかどうかです。$xpath は、特定のノードのみをC14N処理対象とする場合に、XPathでノードを指定します。$nsPrefixes は、名前空間プレフィックスを指定します。
C14N適用に失敗した場合、false が返ります。C14Nを適用する前に、DOMDocument の設定(preserveWhiteSpace、formatOutput など)を確認してください。XPathを使用する場合は、XPathの構文が正しいことを確認し、ノードリストが空でないことを確認する必要があります。また、C14Nの結果は文字列として返されるため、その後の処理で適切に扱うようにしてください。
PHP DomDocument C14N 1.1 でXML正規化する
1<?php 2 3// DomDocument を使用して XML ドキュメントを作成し、C14N 1.1 で正規化する例 4$dom = new DOMDocument('1.0', 'utf-8'); 5$dom->preserveWhiteSpace = false; 6$dom->formatOutput = true; 7 8// ルート要素を作成 9$root = $dom->createElement('root'); 10$dom->appendChild($root); 11 12// 子要素を追加 13$child1 = $dom->createElement('child1', 'some text'); 14$root->appendChild($child1); 15 16$child2 = $dom->createElement('child2'); 17$root->appendChild($child2); 18 19$attr = $dom->createAttribute('attribute1'); 20$attr->value = 'attr_value'; 21$child2->appendChild($attr); 22 23// C14N 1.1 で正規化(排他的、コメントなし) 24$c14n_xml = $dom->C14N(true, false); 25 26if ($c14n_xml === false) { 27 echo "C14N failed\n"; 28} else { 29 echo $c14n_xml . "\n"; 30} 31 32// C14N 1.1 で正規化(コメントあり、名前空間プレフィックスを指定) 33$dom2 = new DOMDocument('1.0', 'utf-8'); 34$dom2->loadXML('<root xmlns:prefix="http://example.org"><child1 prefix:attr="value">text<!-- comment --></child1></root>'); 35 36$nsPrefixes = ['prefix']; 37$c14n_xml_with_comments = $dom2->C14N(true, true, null, $nsPrefixes); 38 39if ($c14n_xml_with_comments === false) { 40 echo "C14N with comments failed\n"; 41} else { 42 echo $c14n_xml_with_comments . "\n"; 43}
PHP 8 の Dom\Document クラスの C14N メソッドは、XML ドキュメントを正規化する機能を提供します。C14N (Canonical XML) とは、XML ドキュメントを標準化された形式に変換するプロセスで、異なるシステム間でのXMLドキュメントの比較やデジタル署名において重要な役割を果たします。
このサンプルコードでは、DOMDocument を使用して XML ドキュメントを作成し、C14N メソッドを使って正規化する方法を示しています。
最初の例では、XML ドキュメントを新規に作成し、要素と属性を追加しています。$dom->C14N(true, false) では、排他的(exclusive = true)かつコメントなし(withComments = false)で正規化を行っています。exclusive が true の場合、ドキュメントノードに直接現れる名前空間ノードのみが出力されます。withComments が false の場合、コメントは出力から除外されます。
2番目の例では、既存の XML ドキュメントをロードし、コメントを含めて正規化しています。$nsPrefixes 配列で名前空間プレフィックスを指定することで、特定の名前空間に関連するノードのみを正規化対象とすることができます。$dom2->C14N(true, true, null, $nsPrefixes) では、排他的(exclusive = true)、コメントあり(withComments = true)、名前空間プレフィックスを指定(nsPrefixes)して正規化しています。
C14N メソッドは、正規化された XML 文字列を返します。エラーが発生した場合は false を返します。このメソッドは、XML データの整合性を保ち、異なる環境間での互換性を高める上で役立ちます。xpath 引数はXPath 式の配列を受け取り、正規化するノードセットを制限できます。
DOMDocument::C14Nメソッドは、XMLドキュメントを正規化する際に使用します。引数 $exclusive は排他的C14Nを指定し、true にするとより厳密な比較に適した形式になります。$withComments はコメントを含めるかどうかを制御します。$xpath で正規化するノードを限定できますが、初心者は null でドキュメント全体を指定することが多いでしょう。$nsPrefixes は名前空間プレフィックスを指定し、これによって出力に含める名前空間を制御できます。エラー処理として、C14N が false を返す場合があるので、必ず戻り値をチェックしましょう。C14NはXMLデータの比較や署名に不可欠な処理ですが、XML構造や名前空間の理解が前提となるため、最初は簡単なXMLで試すことをお勧めします。