【PHP8.x】C14Nメソッドの使い方
C14Nメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
C14Nメソッドは、DOMDocumentTypeクラスのインスタンスに対して、XMLノードを標準的な正規化形式に変換するメソッドです。このメソッドは、XMLの国際標準化機構(W3C)によって定義された「XML正規化(Canonical XML)」の規則に基づいて、XMLドキュメントの内容を一意の表現に変換します。
XML正規化の主な目的は、見た目上同じに見えるXMLドキュメントでも、空白文字の扱いや属性の順序、エンコーディングの違いなどによってバイト表現が異なることを防ぎ、常に同じバイト表現にすることです。これにより、特にデジタル署名を用いてXMLドキュメントの完全性を検証する際など、ドキュメントの内容が改ざんされていないかを正確に判断できるようになります。
C14Nメソッドにはオプションで、排他的正規化を適用するかどうか、そしてXMLコメントを含めるかどうかを指定する引数を渡すことができます。排他的正規化は、特にXMLドキュメントの一部だけを正規化する際に、名前空間の宣言が正しく処理されるようにする方式です。このメソッドは、正規化されたXMLの文字列を返します。
DOMDocumentTypeはXMLドキュメントのDTD(文書型定義)を表すノードであり、このメソッドを使用することで、そのDTD部分を特定の正規化ルールに従って標準化された文字列として取得することが可能です。これは、XMLの構造的な整合性を保証したり、セキュリティ要件を満たす上で重要な機能です。
構文(syntax)
1<?php 2// DOMDocument と DOCTYPE を含む XML を準備 3$xmlString = <<<XML 4<?xml version="1.0" encoding="UTF-8"?> 5<!DOCTYPE root> 6<root></root> 7XML; 8 9$dom = new DOMDocument(); 10$dom->loadXML($xmlString); 11 12// DOMDocumentType オブジェクトを取得 13$docType = $dom->doctype; 14 15// メソッドの構文 16$canonicalString = $docType->C14N( 17 exclusive: false, 18 withComments: false, 19 xpath: null, 20 nsPrefixes: null 21); 22 23// 成功した場合に正規化された文字列を出力 24if ($canonicalString !== false) { 25 echo $canonicalString; 26}
引数(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)
戻り値なし
戻り値はありません
サンプルコード
PHP XML C14N で正規化する
1<?php 2 3// DOMDocumentType::C14N メソッドのサンプルコード 4 5// 新しい DOMDocument を作成します。 6$dom = new DOMDocument('1.0', 'utf-8'); 7 8// ルート要素を作成します。 9$root = $dom->createElement('root'); 10$dom->appendChild($root); 11 12// いくつかの属性を追加します。 13$root->setAttribute('attr1', 'value1'); 14$root->setAttribute('attr2', 'value2'); 15 16// コメントを追加します。 17$comment = $dom->createComment('This is a comment.'); 18$root->appendChild($comment); 19 20// C14N を実行して、標準化された XML を出力します。 21$dom->C14N(); 22 23// C14N を実行して、排他的な標準化された XML を出力します。 24$dom->C14N(true); 25 26// C14N を実行して、コメント付きの標準化された XML を出力します。 27$dom->C14N(false, true); 28 29// C14N を実行して、XPath で指定されたノードのみを標準化します。 30$xpath = array('//root'); 31$dom->C14N(false, false, $xpath); 32 33// C14N を実行して、名前空間プレフィックスを指定して標準化します。 34$nsPrefixes = array('prefix' => 'http://example.com'); 35$dom->C14N(false, false, null, $nsPrefixes); 36 37// C14N を実行して、排他的、コメント付き、XPath、名前空間プレフィックスを指定して標準化します。 38$xpath = array('//root'); 39$nsPrefixes = array('prefix' => 'http://example.com'); 40$dom->C14N(true, true, $xpath, $nsPrefixes); 41?>
このサンプルコードは、PHPのDOMDocumentTypeクラスのC14Nメソッドの使い方を示しています。C14Nメソッドは、XMLドキュメントを標準化する際に使用します。標準化とは、XMLの構造や属性の順序などを一定の規則に従って整理し、同じ内容のXMLであれば常に同じ表現になるように変換することです。
C14Nメソッドは、以下の引数を受け取ります。
$exclusive(bool): 排他的な標準化を行うかどうかを指定します。trueの場合、排他的C14Nが実行されます。デフォルトはfalseです。排他的C14Nは、ドキュメントのコンテキストに関連する名前空間ノードのみを保持します。$withComments(bool): コメントを含めるかどうかを指定します。trueの場合、コメントも出力されます。デフォルトはfalseです。$xpath(?array): 標準化するノードをXPathで指定します。nullの場合、ドキュメント全体が標準化されます。$nsPrefixes(?array): 標準化する名前空間プレフィックスを指定します。
サンプルコードでは、DOMDocumentオブジェクトを作成し、ルート要素や属性、コメントを追加しています。その後、C14Nメソッドを様々な引数の組み合わせで呼び出し、標準化されたXMLを出力します。C14N()のみの呼び出しでは、デフォルトの設定で標準化されます。C14N(true)のように引数を指定することで、排他的な標準化やコメントの出力などのオプションを制御できます。XPathを指定することで、特定のノードのみを標準化することも可能です。戻り値はありません。標準化されたXMLは、通常、出力バッファに直接書き込まれます。
DOMDocumentType::C14Nメソッドは、XMLを標準化するための重要な機能です。引数の$exclusiveは、排他的な標準化を行うかどうかを指定します。trueにすると、より厳密な標準化が行われます。$withCommentsは、コメントを含めるかどうかを制御します。$xpathは、標準化対象を特定のノードに絞り込む際に使用します。XPathの記述を誤ると、意図しない結果になるため注意が必要です。$nsPrefixesは、名前空間プレフィックスを指定します。これを使用する際は、プレフィックスと名前空間URIの対応が正しいか確認してください。C14N実行後、DOMDocumentの内容が変更されるわけではありません。標準化されたXMLを文字列として取得するには、DOMDocument::saveXML()等を利用する必要があります。また、C14Nはセキュリティ上の考慮が必要な場面でも利用されるため、各引数の意味を正しく理解し、適切に設定することが重要です。
PHP XML C14N正規化する
1<?php 2 3/** 4 * XMLドキュメントを正規化 (C14N) するサンプルコード 5 * 6 * DOMDocument::C14N メソッドは、XMLドキュメントを正規化形式の文字列に変換します。 7 * 正規化を行うと、属性の順序や空白文字などが統一され、 8 * 論理的に同じXMLは、物理的に全く同じバイト表現になります。 9 * これは主にXML署名などで、データの同一性を検証するために使用されます。 10 * 11 * @return void 12 */ 13function demonstrateXmlCanonicalization(): void 14{ 15 // 正規化対象のXMLデータ。 16 // 属性の順序がバラバラで、コメントや余分な空白が含まれています。 17 $xmlString = <<<XML 18 <?xml version="1.0" encoding="UTF-8"?> 19 <!-- ドキュメントルート --> 20 <root> 21 <element attribute2="value2" attribute1="value1"> 22 text 23 </element> 24 </root> 25 XML; 26 27 // DOMDocumentオブジェクトを生成し、XMLを読み込む 28 $dom = new DOMDocument(); 29 $dom->loadXML($xmlString); 30 31 // --- パターン1: 標準的な正規化 (コメントなし) --- 32 // C14N (Canonical XML) Version 1.0 に相当します。 33 // コメントは削除され、属性はアルファベット順にソートされます。 34 $c14nString = $dom->C14N( 35 false, // $exclusive: 排他的正規化を無効 36 false // $withComments: コメントを含めない 37 ); 38 echo "--- Standard C14N (without comments) ---\n"; 39 echo $c14nString . "\n\n"; 40 41 // --- パターン2: 排他的正規化 (Exclusive C14N) --- 42 // キーワード「c14n11」は、この排他的正規化の仕様 (XML-EXC-C14N) を指すことがあります。 43 // XML署名などで、XML文書の一部を正規化する際に、不要な名前空間宣言を 44 // 取り除くために使われます。 45 $exclusiveC14nString = $dom->C14N( 46 true, // $exclusive: 排他的正規化を有効 47 false // $withComments: コメントを含めない 48 ); 49 echo "--- Exclusive C14N ---\n"; 50 echo $exclusiveC14nString . "\n\n"; 51 52 // --- パターン3: コメントを含む正規化 --- 53 $c14nWithCommentsString = $dom->C14N( 54 false, // $exclusive: 排他的正規化を無効 55 true // $withComments: コメントを含める 56 ); 57 echo "--- C14N with comments ---\n"; 58 echo $c14nWithCommentsString . "\n"; 59} 60 61// 関数を実行して結果を表示 62demonstrateXmlCanonicalization();
このサンプルコードは、PHPのDOMDocumentクラスのC14Nメソッドを使用して、XMLドキュメントを正規化する例を示しています。XMLの正規化とは、属性の順序や空白を統一し、論理的に同じXMLを常に同じバイト列表現に変換することです。これはXML署名などでデータの同一性を検証する際に重要となります。
DOMDocument::C14Nメソッドは、第一引数$exclusiveで排他的正規化を行うかどうか、第二引数$withCommentsでコメントを含めるかどうかを指定します。排他的正規化は、XML文書の一部分のみを正規化する際に、不要な名前空間宣言を取り除くために使用されます。$xpathと$nsPrefixesは、それぞれXPathと名前空間プレフィックスを指定する場合に使用しますが、この例では省略されています。
サンプルでは、標準的な正規化(コメントなし)、排他的正規化、コメントを含む正規化の3つのパターンを示しています。それぞれの結果を比較することで、C14Nメソッドの挙動を理解できます。このメソッドは戻り値を持たず、正規化されたXML文字列はechoで出力されます。XMLの正規化は、システム間でのデータ交換やXML署名を用いる場合に役立つ技術です。
DOMDocument::C14NはXMLを正規化するメソッドです。引数$exclusiveは排他的正規化を行うかどうかを指定します。trueにすると、XML署名で不要な名前空間宣言が取り除かれます。$withCommentsはコメントを含めるかどうかを決定します。trueの場合、コメントも正規化されます。
正規化を行うとXMLドキュメントが変更されるため、元のXMLを保持しておきたい場合は、正規化前にコピーを作成してください。また、C14NメソッドはエンコーディングをUTF-8に変換して出力します。他のエンコーディングが必要な場合は、正規化後に変換が必要です。XMLの構造によっては、正規化によって結果が大きく変わる可能性があることに注意してください。