Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】DOMNode::C14NFile()メソッドの使い方

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

作成日: 更新日:

基本的な使い方

C14NFileメソッドは、PHPのDOMNodeクラスに属し、XML文書の正規化(Canonicalization)を行い、その結果を指定されたファイルに書き出すためのメソッドです。XMLの正規化とは、XML文書の表現に影響を与えない構文上の差異(例えば、属性の順序、名前空間の宣言方法、空白文字の扱いなど)を標準化し、論理的に同じ内容を持つXML文書が常に同じバイト列に変換されるようにする処理を指します。これにより、デジタル署名などのセキュリティ関連の操作において、XML文書の内容が改ざんされていないことを保証するために利用されます。

このメソッドは、対象となるDOMノードとその子孫ノードを、Canonical XML 1.0の規則に従って正規化します。正規化されたXMLデータは、第一引数で指定したファイルパス($uri)に直接保存されます。第二引数の$exclusivetrueに設定することで、排他的正規化(Exclusive XML Canonicalization)を適用でき、第三引数の$with_commentstrueにすると、出力にコメントを含めることが可能です。さらに、XPath式や名前空間プレフィックスの配列を渡すことで、正規化の対象となる要素をより細かく指定できます。

C14NFileメソッドは、処理が成功した場合、ファイルに書き込まれたバイト数を整数値で返します。何らかの理由で処理が失敗した場合はfalseを返します。この機能は、特にWebサービスやセキュリティシステムでXMLデータを扱う際に、データの整合性を保証するために非常に重要な役割を果たします。

構文(syntax)

1<?php
2// DOMNode クラスのインスタンスが必要です。
3// DOMDocument は DOMNode を継承しているため、ここでは DOMDocument のインスタンスを使用します。
4$domNodeInstance = new DOMDocument();
5$domNodeInstance->loadXML('<root><example_element/></root>');
6
7// C14NFile メソッドの構文
8// string $uri            : 出力先のURI (通常はファイルパス)
9// bool $exclusive       : オプション - 排他的正規化を行うか (デフォルトは false)
10// bool $with_comments   : オプション - コメントを含めるか (デフォルトは false)
11$uri = 'output_normalized.xml';
12$exclusive = false;
13$with_comments = false;
14
15$bytesWritten = $domNodeInstance->C14NFile($uri, $exclusive, $with_comments);
16
17// オプション引数を省略した呼び出し方
18// $bytesWritten = $domNodeInstance->C14NFile($uri);
19?>

引数(parameters)

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

  • string $uri: 正規化するXML文書のURIを指定する文字列
  • bool $exclusive = false: 排他的正規化を行うかどうかを指定する真偽値
  • bool $with_comments = false: コメントを含めて正規化するかどうかを指定する真偽値
  • ?array $xpath = null: 正規化の対象とするノードをXPathで指定する配列
  • ?array $ns_prefixes = null: 名前空間のプレフィックスを正規化の際に使用するかどうかを指定する配列

戻り値(return)

bool

C14NFileメソッドは、ノードを正規化してファイルに保存できるかどうかを示す真偽値(trueまたはfalse)を返します。

サンプルコード

PHP DOMNode::C14NFile でXMLを正規化する

1<?php
2
3/**
4 * XML文字列を正規化し、その結果をファイルに保存するサンプル関数です。
5 * DOMNode::C14NFile メソッドを使用します。
6 *
7 * @param string $xmlString 正規化したいXMLデータを含む文字列。
8 * @return void
9 */
10function demonstrateC14NFileUsage(string $xmlString): void
11{
12    // DOMDocument オブジェクトを初期化
13    $dom = new DOMDocument('1.0', 'UTF-8');
14    // XMLパースエラーを内部で処理し、警告表示を抑止
15    libxml_use_internal_errors(true);
16
17    // XML文字列をDOMDocumentにロード
18    if (!$dom->loadXML($xmlString)) {
19        echo "エラー: XML文字列のロードに失敗しました。\n";
20        // 発生したXMLパースエラーを表示
21        foreach (libxml_get_errors() as $error) {
22            echo " - " . trim($error->message) . "\n";
23        }
24        libxml_clear_errors(); // エラーバッファをクリア
25        return;
26    }
27
28    // 正規化されたXMLを保存する一時ファイルパスを定義
29    $outputFilePath = 'canonicalized_output.xml';
30
31    echo "--- 元のXML文書 ---\n";
32    echo $dom->saveXML() . "\n";
33
34    // DOMNode::C14NFile メソッドでXMLを正規化し、ファイルに保存
35    // 第1引数: 結果を書き込むファイルパス ($uri)
36    // 第2引数: 排他的正規化を行うか (false = デフォルトのXML-C14N)
37    // 第3引数: コメントを含めるか (true = コメントを含める)
38    $success = $dom->C14NFile($outputFilePath, false, true);
39
40    if ($success) {
41        echo "\nXMLの正規化に成功し、'{$outputFilePath}' に保存されました。\n";
42        if (file_exists($outputFilePath)) {
43            echo "\n--- 正規化されたXMLの内容 ('{$outputFilePath}') ---\n";
44            echo file_get_contents($outputFilePath) . "\n";
45
46            // クリーンアップ: 生成されたファイルを削除
47            unlink($outputFilePath);
48            echo "\nクリーンアップ: '{$outputFilePath}' を削除しました。\n";
49        } else {
50            echo "\nエラー: 正規化された出力ファイルが見つかりません。\n";
51        }
52    } else {
53        echo "\nエラー: XMLの正規化に失敗しました。\n";
54    }
55}
56
57// サンプルXMLデータ
58// XML正規化 (C14N) は、属性の順序、空要素の表現、名前空間の宣言などを統一します。
59$sampleXml = <<< 'XML'
60<?xml version="1.0" encoding="UTF-8"?>
61<root a="1" b="2" c="3">
62    <!-- これはコメントです -->
63    <child id="item1">
64        Hello, World!
65    </child>
66    <other-child xmlns:prefix="http://example.com/ns">
67        <prefix:data>Namespace content</prefix:data>
68        <empty-tag/>
69    </other-child>
70</root>
71XML;
72
73// 関数を実行し、DOMNode::C14NFile の動作を確認
74demonstrateC14NFileUsage($sampleXml);
75
76?>

PHP 8のDOMNode::C14NFileメソッドは、XML文書を正規化(Canonicalization; C14N)し、その結果を指定したファイルに保存する機能を提供します。XML正規化とは、XML文書の論理的な意味を変えずに、その物理的な表現を一意の形式に変換するプロセスです。例えば、属性の順序や空要素の表現、名前空間の宣言方法などを統一し、XML文書の比較やデジタル署名に適した形式にします。

このメソッドは、第一引数string $uriで正規化されたXMLを書き込むファイルパスを指定します。第二引数bool $exclusiveは排他的正規化を行うかどうかを設定し、falseを指定すると標準のXML-C14Nが適用されます。第三引数bool $with_commentsは、正規化後の出力にXMLコメントを含めるかどうかを制御します。処理が成功した場合はtrue、失敗した場合はfalseを戻り値として返します。

サンプルコードでは、与えられたXML文字列をDOMDocumentオブジェクトにロードした後、C14NFileメソッドを使ってXMLを正規化し、canonicalized_output.xmlというファイルに保存しています。exclusivefalsewith_commentstrueに設定しているため、標準的な正規化が行われ、元のXMLに含まれるコメントも出力ファイルに含められます。処理の成功・失敗に応じてメッセージが表示され、成功時には生成されたファイルの内容を確認後、削除する一連の流れを確認できます。

このサンプルコードは、XMLを正規化してファイルに保存するDOMNode::C14NFileメソッドの使用例です。注意点として、正規化結果を保存するファイルパスには書き込み権限が必須で、存在しないディレクトリを指定するとエラーとなります。また、XML文字列のロード(loadXML)や正規化(C14NFile)が失敗した際にはfalseが返されますので、必ず戻り値をチェックし、適切なエラーハンドリングを行うことが重要です。特にlibxml_use_internal_errorslibxml_get_errorsを活用し、XMLパースのエラー原因を特定する習慣をつけましょう。C14NFileの引数である排他的正規化やコメントの有無は、正規化されたXMLの内容に影響を与えるため、目的に合わせて正しく設定してください。最後に、一時的に作成したファイルはunlink関数で必ず削除し、クリーンアップを徹底してください。

PHP DOM C14NFileでXMLを正規化保存する

1<?php
2
3/**
4 * DOMNode::C14NFile メソッドのサンプルコード
5 *
6 * この関数は、DOMDocument の内容を W3C XML 1.0 Canonicalization (C14N) 形式に正規化し、
7 * その結果を新しいファイルとして保存します。
8 * キーワード「php cp」に関連し、DOMツリーの構造化されたデータをXMLとして「コピー」し、
9 * 指定されたファイルパスに出力(保存)する操作を示します。
10 *
11 * @return bool ファイルの保存が成功した場合は true、失敗した場合は false を返します。
12 */
13function saveDomAsC14NFile(): bool
14{
15    // 1. 新しいDOMDocumentインスタンスを作成
16    // XMLバージョン1.0、エンコーディングUTF-8を指定
17    $dom = new DOMDocument('1.0', 'UTF-8');
18    // 出力時にXMLを整形するための設定(C14NFileの出力には直接影響しませんが、
19    // 通常のDOM操作でのXML整形時に便利です)
20    $dom->formatOutput = true;
21
22    // 2. DOMツリーを構築
23    // ルート要素 'root' を作成し、ドキュメントに追加
24    $root = $dom->createElement('root');
25    $dom->appendChild($root);
26
27    // 子要素 'item' を作成し、属性とテキストノードを追加
28    $item1 = $dom->createElement('item');
29    $item1->setAttribute('id', 'item_one');
30    $item1->nodeValue = '最初のコンテンツ';
31    $root->appendChild($item1);
32
33    // 別の 'item' 要素
34    $item2 = $dom->createElement('item');
35    $item2->setAttribute('id', 'item_two');
36    $item2->nodeValue = '二番目のコンテンツ';
37    $root->appendChild($item2);
38
39    // コメントノードを追加
40    // C14NFileメソッドで $with_comments を true に設定すると、このコメントも出力に含まれます。
41    $comment = $dom->createComment('これは正規化された出力に含まれるコメントです。');
42    $root->appendChild($comment);
43
44    // 3. 保存するファイルパスを指定
45    // このスクリプトと同じディレクトリに 'output_c14n_example.xml' という名前で保存します。
46    // このパスは、実行環境でPHPに書き込み権限がある場所である必要があります。
47    $outputFilePath = __DIR__ . '/output_c14n_example.xml';
48
49    // 4. DOMNode::C14NFile メソッドを呼び出して、DOMの内容を正規化されたXMLとしてファイルに保存
50    // 引数について:
51    //   $uri:           保存先のファイルURI (例: 'file:///path/to/output.xml')
52    //   $exclusive:     排他的正規化を行うか (false = 非排他的正規化、W3C勧告のデフォルト形式)
53    //   $with_comments: コメントノードを正規化された出力に含めるか (true = 含める)
54    //   $xpath:         特定のノードのサブセットを正規化する場合にXPath式を配列で指定 (今回はnullでドキュメント全体)
55    //   $ns_prefixes:   特定の名前空間プレフィックスのセットを正規化する場合に配列で指定 (今回はnullで制限なし)
56    $success = $dom->C14NFile(
57        $outputFilePath,
58        false, // $exclusive を false に設定し、非排他的正規化を行います。
59        true   // $with_comments を true に設定し、XMLコメントを出力に含めます。
60        // $xpath および $ns_prefixes はデフォルト値 (null) を使用し、ドキュメント全体を対象とします。
61    );
62
63    // 5. 結果を返す
64    // この関数を呼び出した側で、戻り値の真偽を確認することで、ファイルの保存が成功したか失敗したかを判断できます。
65    return $success;
66}
67
68// saveDomAsC14NFile 関数を実行します。
69// 実行後、指定したパスに 'output_c14n_example.xml' ファイルが生成されます。
70// 例: $isSaved = saveDomAsC14NFile();
71//     if ($isSaved) { echo "ファイルが正常に保存されました。"; } else { echo "ファイルの保存に失敗しました。"; }
72saveDomAsC14NFile();

PHPのDOMNode::C14NFileメソッドは、DOMDocumentオブジェクトの内容をW3C XML 1.0 Canonicalization (C14N) という標準形式に正規化し、その結果を指定されたファイルに保存する機能を提供します。これは、XMLドキュメントの内容を、見た目の整形や空白文字、属性の順序などの違いに影響されずに、常に一意な形式で表現するために使用されます。キーワード「php cp」が示すように、DOMツリーという構造化されたデータをXMLとして「コピー」し、ファイルに出力する操作と捉えることができます。

このメソッドは、引数として保存先のファイルパスをURI形式で受け取ります。$exclusive引数で排他的正規化を行うかを、$with_comments引数でコメントノードを出力に含めるかを指定できます。$xpath$ns_prefixes引数を使用すると、ドキュメント全体ではなく、特定のノードや名前空間に限定して正規化を行うことも可能です。

サンプルコードでは、まずDOMDocumentを作成し、ルート要素や子要素、テキストノード、コメントノードを順に構築しています。その後、C14NFileメソッドを呼び出し、構築したDOMツリーの内容を「output_c14n_example.xml」というファイルに正規化されたXMLとして保存しています。$with_commentstrueに設定することで、ドキュメント内のコメントも出力ファイルに含まれるようになります。メソッドは処理の成功・失敗をtrueまたはfalseのブール値で返しますので、ファイルの保存が正常に行われたかを確認することができます。

DOMNode::C14NFileメソッドは、DOMツリーをW3CのXML正規化(C14N)形式でファイルに保存します。この際、指定するファイルパスにはPHPが書き込み可能な権限が必須である点にご注意ください。通常のファイルコピー(php cp)とは異なり、XML構造が標準化された形式で出力されるため、バイト列は元のXMLとは異なる場合があります。

コメントを含めるには$with_comments引数をtrueに設定する必要があり、これが初心者が間違いやすい点です。メソッドの戻り値は成功・失敗を表すbool型ですので、必ずその結果を確認し、失敗時の処理を検討してください。また、引数$uriにはファイルパスをURI形式で指定します。これらの注意点を踏まえ、安全にご利用ください。

関連コンテンツ

関連IT用語

関連プログラミング言語