【PHP8.x】Dom\Entity::C14N()メソッドの使い方
C14Nメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『C14Nメソッドは、Dom\EntityオブジェクトをW3Cの仕様に基づいた正規形(Canonical Form)の文字列に変換する処理を実行するメソッドです。正規化(Canonicalization)とは、XML文書において意味的には同じでも、属性の順序や空白の扱いなどが異なる多様な表現を、特定のルールに従って一意の形式に変換するプロセスを指します。この処理により、例えば電子署名の検証やデータの同一性確認を行う際に、見た目の違いに影響されずに、2つのXML文書が論理的に等価であるかをバイトレベルで正確に比較できるようになります。このメソッドは、呼び出されたエンティティノードとその子孫ノードを対象に正規化を行い、その結果を文字列として返します。オプションの引数を指定することで、コメントノードを含めるか、排他的正規化(Exclusive Canonicalization)を適用するかといった、より詳細な動作を制御することも可能です。処理に成功した場合は正規化された文字列を、失敗した場合はfalseを返します。』
構文(syntax)
1$result = $entity->C14N($xpathQuery, $exclusive, $withComments, $nsPrefixes);
引数(parameters)
bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null
- bool $exclusive: true に設定すると、文書全体ではなく、指定されたノードのみを正規化します。デフォルトは
falseです。 - bool $withComments: true に設定すると、コメントノードも正規化に含めます。デフォルトは
falseです。 - ?array $xpath: 正規化の対象とするノードをXPath式で指定します。指定しない場合は文書全体が対象です。
- ?array $nsPrefixes: 名前空間のプレフィックスをキー、URIを値とする連想配列を指定します。正規化の際に、これらのプレフィックスのみが使用されるようにします。
戻り値(return)
string|false
C14Nメソッドは、XML文書を正規化(Canonicalization)した結果を文字列で返します。正規化に失敗した場合はfalseを返します。
サンプルコード
PHPによるXMLのC14N正規化
1<?php 2 3/** 4 * XML文字列をDOMDocumentオブジェクトに読み込み、 5 * C14N()メソッドを使って正規化(Canonicalization)するサンプルコードです。 6 * 7 * 正規化とは、論理的に等価なXML文書が、物理的(バイト単位)にも 8 * 同じ表現になるように変換するプロセスです。 9 * 例えば、属性の順序を統一したり、不要な空白を削除したりします。 10 * これは、XML署名の検証など、XMLデータの一貫性が重要な場面で利用されます。 11 */ 12function demonstrateXmlC14N(): void 13{ 14 // 正規化の対象となるXML文字列を定義します。 15 // 属性の順序がバラバラで、不要な空白やコメントが含まれています。 16 $originalXml = <<<XML 17 <?xml version="1.0" encoding="UTF-8"?> 18 <!-- 商品リスト --> 19 <root> 20 <item name="ペン" id="item-2" > 21 <price>100</price> 22 </item> 23 <item id="item-1" name="ノート"> 24 <price>150</price> 25 </item> 26 </root> 27 XML; 28 29 // DOMDocumentオブジェクトを作成し、XMLを読み込みます。 30 $dom = new DOMDocument(); 31 // 整形のための不要な空白ノードを保持しないように設定します。 32 $dom->preserveWhiteSpace = false; 33 $dom->loadXML($originalXml); 34 35 // ドキュメント全体(DOMDocumentオブジェクト自体がノードです)に対して 36 // C14N() メソッドを呼び出し、正規化されたXML文字列を取得します。 37 // 38 // C14N(bool $exclusive = false, bool $withComments = false, ...): string|false 39 // - 第1引数 (exclusive): 排他的正規化を行うかどうか。 40 // - 第2引数 (withComments): コメントノードを含めるかどうか。 41 // 42 // ここではコメントを含めて正規化($withComments = true)します。 43 $canonicalXml = $dom->C14N(false, true); 44 45 // 結果をプレーンテキストとして出力します。 46 header('Content-Type: text/plain; charset=utf-8'); 47 48 echo "--- 元のXML ---" . PHP_EOL; 49 echo $originalXml . PHP_EOL . PHP_EOL; 50 51 echo "--- C14Nで正規化後のXML(コメントあり)---" . PHP_EOL; 52 if ($canonicalXml !== false) { 53 // 属性の順序が 'id', 'name' に統一され、 54 // 要素間の不要な空白が削除されていることがわかります。 55 echo $canonicalXml . PHP_EOL; 56 } else { 57 echo "正規化に失敗しました。" . PHP_EOL; 58 } 59} 60 61// 関数を実行します。 62demonstrateXmlC14N();
Dom\Entity::C14N()は、XML文書を正規化(Canonicalization)するためのメソッドです。正規化とは、属性の順序や空白の有無といった表現上の差異を吸収し、論理的に同じ意味を持つXML文書が物理的(バイト単位)に全く同じ表現になるように変換する処理のことです。この処理は、XML署名の検証など、データの同一性を厳密に保証する必要がある場面で利用されます。
このメソッドはDOMDocumentやDOMElementなどのノードオブジェクトに対して呼び出します。第1引数$exclusiveは、排他的正規化を行うかを真偽値で指定します。第2引数$withCommentsは、変換後の文字列にXMLコメントを含めるかを真偽値で指定します。サンプルコードでは、コメントを含める設定でこのメソッドを実行しています。その結果、元のXMLでバラバラだった属性の順序が統一され、要素間の不要な空白が削除された、正規のXML文字列が生成されます。
メソッドの戻り値は、処理が成功した場合は正規化されたXML文字列、何らかの理由で失敗した場合はfalseとなります。
このメソッドは処理に失敗するとfalseを返すため、サンプルコードのように戻り値を厳密にチェックすることが不可欠です。DOMDocumentオブジェクトだけでなく、特定のDOMElementノードに対しても呼び出し可能で、XMLの一部だけを正規化できます。出力される文字列は常にUTF-8でエンコードされます。また、このメソッドはW3C勧告の「Canonical XML Version 1.0」に基づいているため、より新しい仕様が必要な場合は注意が必要です。巨大なXMLを扱う際は、処理時間やメモリ消費が増加する可能性も考慮すると、より安全なコードになります。