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

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

作成日: 更新日:

基本的な使い方

C14Nメソッドは、DOM (Document Object Model) の CDATASection ノードを、W3C勧告の Canonical XML Version 1.0 に従って、正規化されたXMLにシリアライズ(変換)するメソッドです。CDATASection は、XMLドキュメント内で解析されない文字データを記述するために使用されます。C14Nメソッドを使用することで、XMLドキュメントの一部分(この場合はCDATASection)を、特定の形式に変換し、一貫性のある表現を得ることができます。

このメソッドは、Dom\CDATASection クラスのインスタンスに対して呼び出され、CDATASectionノードの内容を正規化された文字列として返します。正規化とは、XMLドキュメントを表現する上で、空白の扱い、属性の順序、名前空間の宣言など、様々な要素を一定の規則に従って整理することを指します。

C14Nメソッドは、異なるシステム間でXMLデータを交換する際や、XMLデータを比較・検証する際に役立ちます。なぜなら、C14NによってXMLの表現が統一されるため、形式の違いによる誤認識を防ぐことができるからです。例えば、異なるXMLエディタで作成されたドキュメントでも、C14Nを適用すれば、内容が同じであれば同じ文字列として表現されるようになります。

C14Nメソッドを使用する際には、出力されるXMLの文字エンコーディングや、名前空間の処理方法など、いくつかのオプションを指定することができます。これらのオプションを適切に設定することで、より詳細な制御が可能となり、目的に応じた正規化を行うことができます。システム開発においては、XMLデータの整合性を保ち、相互運用性を高めるために重要な役割を果たします。

構文(syntax)

1public Dom\CDATASection::C14N(string $exclusive = "", bool $with_comments = true, ?array $nodes = null, string $namespacePrefixes = ""): bool

引数(parameters)

bool $exclusive = false, bool $with_comments = false, ?array $xpath = null, ?array $ns_prefixes = null

  • bool $exclusive = false: 排他的な名前空間の正規化を行うかどうかを指定します。trueの場合、現在のノードに直接関連する名前空間のみが正規化されます。
  • bool $with_comments = false: コメントを含めて正規化するかどうかを指定します。
  • ?array $xpath = null: 正規化から除外するXPathセレクタの配列を指定します。
  • ?array $ns_prefixes = null: 正規化の対象とする名前空間プレフィックスの配列を指定します。

戻り値(return)

string|false

このメソッドは、XMLまたはHTMLドキュメントを標準的な形式(C14N)に正規化して文字列として返します。正規化に失敗した場合は false を返します。

サンプルコード

PHP CDATASection C14N処理

1<?php
2
3/**
4 * Dom\CDATASection::C14N メソッドの使用例を示します。
5 *
6 * この関数は、XMLドキュメント内のCDATAセクションノードを取得し、
7 * そのノードに対してXMLの正規化(Canonicalization, C14N)を適用する方法をデモンストレーションします。
8 *
9 * キーワード "c14n11" はXML Canonicalization 1.1を指しますが、
10 * Dom\Node::C14N メソッドは主にXML Canonicalization 1.0 および Exclusive Canonicalization 1.0 に対応しています。
11 * Dom\CDATASection ノード単体の正規化は、そのテキストコンテンツをそのまま返すことが多く、
12 * XML構造全体の正規化とは異なる点に注意が必要です。
13 *
14 * システムエンジニアを目指す初心者向けに、簡潔かつ正確なコードを提供します。
15 */
16function demonstrateCdataSectionC14N(): void
17{
18    // サンプル XML ドキュメントを定義
19    $xmlString = <<<XML
20<root xmlns:ex="http://example.com/ns">
21    <data attr="value">
22        <!-- これはXMLコメントです -->
23        <![CDATA[This is <b>CDATA</b> content with <special> characters & entities.</special>]]>
24    </data>
25    <info>Some other text.</info>
26</root>
27XML;
28
29    // Dom\Document オブジェクトを作成し、XML をロード
30    $dom = new Dom\Document();
31    $dom->loadXML($xmlString);
32
33    echo "オリジナル XML:\n";
34    // `saveXML()` は、XML宣言や適切なインデントを含む整形されたXMLを出力します。
35    echo $dom->saveXML();
36    echo "\n";
37
38    // CDATASection ノードを検索
39    $cdataSection = null;
40    $dataElements = $dom->getElementsByTagName('data');
41    if ($dataElements->count() > 0) {
42        // 'data' 要素の子ノードを走査し、Dom\CDATASection のインスタンスを見つける
43        foreach ($dataElements->item(0)->childNodes as $node) {
44            if ($node instanceof Dom\CDATASection) {
45                $cdataSection = $node;
46                break; // 最初に見つかった CDATASection を使用
47            }
48        }
49    }
50
51    if ($cdataSection !== null) {
52        echo "取得した CDATASection のテキストコンテンツ:\n";
53        echo $cdataSection->textContent . "\n\n";
54
55        // --- Dom\CDATASection::C14N メソッドの呼び出し例 ---
56
57        // 1. 標準的な C14N (XML C14N 1.0)
58        // 引数: exclusive=false (標準正規化), with_comments=false (コメントを含まない)
59        // CDATASection ノード単体のC14Nは、その生のテキストコンテンツを返します。
60        // XML構造(要素、属性、名前空間)の正規化とは異なり、CDATA内部のテキストは変更されません。
61        echo "CDATASection の C14N (標準、コメントなし):\n";
62        $c14nResultStandard = $cdataSection->C14N(false, false);
63        if ($c14nResultStandard !== false) {
64            echo $c14nResultStandard . "\n\n";
65        } else {
66            echo "C14N 処理に失敗しました。\n\n";
67        }
68
69        // 2. 排他的 C14N (Exclusive XML C14N 1.0)
70        // 引数: exclusive=true (排他的正規化), with_comments=false (コメントを含まない)
71        // 排他的正規化は名前空間宣言の伝播を制御しますが、CDATASection ノード自体は名前空間を持たないため、
72        // この例では標準C14Nと同じ結果になります。
73        echo "CDATASection の C14N (排他的、コメントなし):\n";
74        $c14nResultExclusive = $cdataSection->C14N(true, false);
75        if ($c14nResultExclusive !== false) {
76            echo $c14nResultExclusive . "\n\n";
77        } else {
78            echo "C14N (排他的) 処理に失敗しました。\n\n";
79        }
80
81        // 3. コメントを含む標準 C14N
82        // 引数: exclusive=false (標準正規化), with_comments=true (コメントを含む)
83        // Dom\CDATASection ノード自体はコメントを持たないため、この引数を true にしても
84        // このノード単体のC14N結果に直接的な変化はありません。コメントは親ノードに属します。
85        echo "CDATASection の C14N (標準、コメントあり):\n";
86        $c14nResultWithComments = $cdataSection->C14N(false, true);
87        if ($c14nResultWithComments !== false) {
88            echo $c14nResultWithComments . "\n\n";
89        } else {
90            echo "C14N (コメントあり) 処理に失敗しました。\n\n";
91        }
92
93    } else {
94        echo "エラー: XML ドキュメントから CDATASection ノードが見つかりませんでした。\n";
95    }
96}
97
98// サンプル関数を実行
99demonstrateCdataSectionC14N();
100

PHPのDom\CDATASection::C14Nメソッドは、XMLドキュメント内のCDATAセクションノードに対してXMLの正規化(Canonicalization, C14N)を適用する際に使用されます。C14Nは、XMLドキュメントの内容が論理的に等しいかを判断するために、見た目や記述方法の違いを吸収し、一貫した表現形式に変換するプロセスです。

このメソッドは、第一引数$exclusiveで排他的C14N(名前空間の扱いを限定する方式)を行うかを、第二引数$with_commentsで正規化結果にコメントを含めるかを真偽値で指定します。オプションの$xpath$ns_prefixes引数は、正規化の対象を絞り込むために使われます。処理が成功すると正規化されたXMLの文字列が返され、失敗した場合はfalseが戻り値となります。

サンプルコードでは、XMLドキュメントからCDATAセクションノードを見つけ出し、そのノードに対してC14Nメソッドを呼び出しています。CDATAセクションノード単体での正規化は、通常、その内部のテキストコンテンツをそのまま出力します。これは、XMLドキュメント全体を構成する要素や属性、名前空間宣言などを対象とする正規化とは異なり、CDATA内部のテキスト自体が変更されることはありません。そのため、$exclusive$with_comments引数の設定が、CDATAセクション単体のC14N結果に直接的な影響を与えることは少ないです。なお、このメソッドは主にXML Canonicalization 1.0に対応しており、キーワードの"c14n11"が示すより新しいバージョンとは直接的な関係はありません。

Dom\CDATASection::C14Nメソッドは、XMLドキュメント全体ではなく、指定したCDATAセクションノードの内部テキストコンテンツのみを正規化します。その内容は通常、そのまま返されます。引数$exclusive$with_commentsは、CDATAセクション単体では結果にほとんど影響せず、要素やドキュメント全体の正規化で効果を発揮します。処理失敗時にはfalseが返るため、必ず戻り値を確認しエラー処理を行ってください。PHPのC14Nは主にXML Canonicalization 1.0に対応しており、「c14n11」というキーワードとは動作が異なる点にご留意ください。

関連コンテンツ

関連プログラミング言語