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

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

作成日: 更新日:

基本的な使い方

schemaValidateメソッドは、DOMDocumentオブジェクトが表すXMLドキュメントに対して、指定されたスキーマに基づいたバリデーションを実行するメソッドです。具体的には、XMLドキュメントの構造や内容が、参照するスキーマ定義に準拠しているかどうかを検証します。

このメソッドは、XMLドキュメントの整合性を保証するために重要な役割を果たします。スキーマは、XMLドキュメントが従うべきルールを定義するものであり、要素、属性、データの型などを指定します。schemaValidateメソッドを使用することで、XMLドキュメントがこれらのルールに違反していないかを確認できます。

バリデーションが成功した場合、つまりXMLドキュメントがスキーマに準拠している場合、このメソッドはTRUEを返します。一方、バリデーションに失敗した場合、つまりXMLドキュメントがスキーマに違反している場合、このメソッドはFALSEを返します。バリデーションエラーが発生した場合、エラーメッセージはlibxmlのエラーバッファに格納されます。これらのエラーメッセージは、libxml_get_errors()関数を使用して取得できます。

schemaValidateメソッドは、XMLドキュメントの妥当性を確認し、データ交換や処理におけるエラーを未然に防ぐために役立ちます。特に、外部システムとの連携や、複雑なXML構造を扱う場合に有効です。XMLドキュメントの信頼性を高め、アプリケーションの安定性を向上させるために、積極的に活用することが推奨されます。

構文(syntax)

1public Dom\Document::schemaValidate(string $filename, int $flags = 0): bool

引数(parameters)

string $filename, int $flags = 0

  • string $filename: 検証に使用するスキーマファイルのパスを指定します。
  • int $flags = 0: 検証の挙動を制御するフラグを指定します。デフォルトは0で、フラグは指定されません。

戻り値(return)

bool

Dom\Document::schemaValidate メソッドは、XML 文書が指定されたスキーマに対して有効かどうかを検証し、その結果を真偽値(bool)で返します。検証が成功した場合は true を、失敗した場合は false を返します。

サンプルコード

PHP DOM schemaValidate でXMLを検証する

1<?php
2
3/**
4 * XMLファイルをXSDスキーマで検証するサンプル関数。
5 *
6 * この関数は、提供されたXMLコンテンツを一時ファイルとして保存し、
7 * 同じく提供されたXSDスキーマコンテンツを使用して検証します。
8 * 検証後、一時ファイルは削除されます。
9 * システムエンジニアを目指す初心者の方のために、XMLスキーマ検証の基本的な流れと
10 * エラーハンドリングを含んでいます。
11 *
12 * @param string $xmlContent 検証するXMLの内容を表す文字列。
13 * @param string $xsdContent 検証に使用するXSDスキーマの内容を表す文字列。
14 * @return bool 検証が成功した場合は true、失敗した場合は false を返します。
15 */
16function validateXmlAgainstSchema(string $xmlContent, string $xsdContent): bool
17{
18    // 一時的なXMLファイルとXSDファイルを作成するためのパスを生成します。
19    // sys_get_temp_dir() はシステムの一時ディレクトリを返します。
20    $xmlFilename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'sample_xml_' . uniqid() . '.xml';
21    $xsdFilename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'sample_xsd_' . uniqid() . '.xsd';
22
23    // XMLコンテンツを一時ファイルに書き込みます。
24    if (file_put_contents($xmlFilename, $xmlContent) === false) {
25        echo "エラー: XML一時ファイルの作成に失敗しました。\n";
26        return false;
27    }
28
29    // XSDスキーマコンテンツを一時ファイルに書き込みます。
30    if (file_put_contents($xsdFilename, $xsdContent) === false) {
31        echo "エラー: XSD一時ファイルの作成に失敗しました。\n";
32        // XSDファイルの作成に失敗した場合、作成済みのXMLファイルも削除します。
33        unlink($xmlFilename);
34        return false;
35    }
36
37    // Dom\Document クラスのインスタンスを作成します。
38    // このクラスはXML文書を操作するための機能を提供します。
39    $dom = new Dom\Document();
40
41    // XMLパーサーからのエラーを内部的に処理するように設定します。
42    // これにより、エラーが発生してもPHPが警告を発せずに、libxml_get_errors() で詳細を取得できます。
43    libxml_use_internal_errors(true);
44
45    // XMLファイルを読み込みます。
46    if (!$dom->load($xmlFilename)) {
47        echo "エラー: XMLファイルの読み込みに失敗しました。\n";
48        // 読み込み失敗時のLibXMLエラー情報を表示します。
49        foreach (libxml_get_errors() as $error) {
50            echo "  LibXMLエラー: " . $error->message;
51        }
52        libxml_clear_errors(); // エラー情報をクリア
53        unlink($xmlFilename);
54        unlink($xsdFilename);
55        return false;
56    }
57    libxml_clear_errors(); // 以前のXML読み込みエラー情報をクリア
58
59    // Dom\Document::schemaValidate メソッドを使用して、読み込んだXMLをXSDスキーマで検証します。
60    // 戻り値は検証が成功した場合は true、失敗した場合は false です。
61    $isValid = $dom->schemaValidate($xsdFilename);
62
63    // 検証結果をユーザーに通知します。
64    if ($isValid) {
65        echo "検証結果: XMLはXSDスキーマに対して有効です。\n";
66    } else {
67        echo "検証結果: XMLはXSDスキーマに対して無効です。\n";
68        echo "検証エラーの詳細:\n";
69        // 検証が失敗した場合、LibXMLのエラー情報を表示して詳細を提供します。
70        foreach (libxml_get_errors() as $error) {
71            echo "  LibXMLエラー: " . $error->message;
72        }
73        libxml_clear_errors(); // エラー情報をクリア
74    }
75
76    // 作成した一時ファイルを削除します。
77    unlink($xmlFilename);
78    unlink($xsdFilename);
79
80    return $isValid;
81}
82
83// --- サンプルコードの実行例 ---
84
85// 有効なXMLの例
86$validXmlContent = <<<XML
87<?xml version="1.0" encoding="UTF-8"?>
88<bookstore>
89    <book category="cooking">
90        <title lang="en">Everyday Italian</title>
91        <author>Giada De Laurentiis</author>
92        <year>2005</year>
93        <price>30.00</price>
94    </book>
95    <book category="children">
96        <title lang="en">Harry Potter</title>
97        <author>J.K. Rowling</author>
98        <year>2005</year>
99        <price>29.99</price>
100    </book>
101</bookstore>
102XML;
103
104// 対応するXSDスキーマの例
105$sampleXsdContent = <<<XSD
106<?xml version="1.0" encoding="UTF-8"?>
107<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
108    <xs:element name="bookstore">
109        <xs:complexType>
110            <xs:sequence>
111                <xs:element name="book" maxOccurs="unbounded">
112                    <xs:complexType>
113                        <xs:sequence>
114                            <xs:element name="title" type="xs:string"/>
115                            <xs:element name="author" type="xs:string"/>
116                            <xs:element name="year" type="xs:integer"/>
117                            <xs:element name="price" type="xs:decimal"/>
118                        </xs:sequence>
119                        <xs:attribute name="category" type="xs:string" use="required"/>
120                    </xs:complexType>
121                </xs:element>
122            </xs:sequence>
123        </xs:complexType>
124    </xs:element>
125</xs:schema>
126XSD;
127
128echo "--- 有効なXMLの検証 --- \n";
129validateXmlAgainstSchema($validXmlContent, $sampleXsdContent);
130echo "\n";
131
132// 無効なXMLの例(price要素の型がXSDではdecimalなのに文字列になっている)
133$invalidXmlContent = <<<XML
134<?xml version="1.0" encoding="UTF-8"?>
135<bookstore>
136    <book category="cooking">
137        <title lang="en">Everyday Italian</title>
138        <author>Giada De Laurentiis</author>
139        <year>2005</year>
140        <price>THIRTY</price> <!-- ここがdecimal型ではなく文字列になっている -->
141    </book>
142</bookstore>
143XML;
144
145echo "--- 無効なXMLの検証 --- \n";
146validateXmlAgainstSchema($invalidXmlContent, $sampleXsdContent);
147
148?>

PHPのDom\Document::schemaValidateメソッドは、XML文書がXML Schema Definition(XSD)ファイルに定義された構造やデータ型に準拠しているかを検証するために使用されます。このメソッドはDom\Documentクラスのインスタンスに対して呼び出され、既に読み込まれたXML文書を対象とします。

第1引数 $filename には、検証に使用するXSDスキーマファイルのパスを文字列で指定します。第2引数 $flags はオプションで、検証時の振る舞いを調整するための整数値を指定できますが、通常はデフォルト値の 0 で問題ありません。

メソッドの戻り値は bool 型で、XML文書がXSDスキーマの要件をすべて満たしていれば true を、一つでも満たしていなければ false を返します。

サンプルコードでは、XMLとXSDの内容を一時ファイルに保存し、Dom\DocumentオブジェクトにXMLを読み込ませた後、schemaValidateメソッドを呼び出して検証を実行しています。検証の際には、libxml_use_internal_errors関数を true に設定することで、検証エラーが発生した場合にPHPが警告を発するのを抑制し、libxml_get_errors関数で詳細なエラーメッセージを取得できるようにしています。この機能は、外部システムから受け取ったXMLデータが想定通りの形式であるかを確認し、不正なデータを早期に検出する際に非常に役立ちます。

Dom\Document::schemaValidateメソッドは、XMLやXSDのファイルパスを引数として受け取るため、文字列データから検証する際は、サンプルコードのように一時ファイルを生成し、利用後に必ず削除することが重要です。リソースの無駄遣いやセキュリティリスクを防ぎましょう。検証結果が失敗した場合、libxml_use_internal_errors(true)を設定し、libxml_get_errors()で詳細なエラーメッセージを取得する手法が不可欠です。これにより、何が問題だったかを正確に把握できます。また、スキーマ検証以前にDom\Document::load()でXML自体が正しく読み込めるかを確認することも忘れないでください。

PHP XML schemaValidate で検証する

1<?php
2
3// PHP 8以降のDom\Documentクラスを使用します。
4// 以前のバージョンではDOMDocumentクラスが使用されていました。
5
6/**
7 * 指定されたXML文字列をXSDスキーマファイルに対して検証する関数。
8 *
9 * システムエンジニアを目指す初心者の方へ:
10 * この関数は、XMLデータが定義されたルール(スキーマ)に準拠しているかを確認するために使用します。
11 * 例えば、WebサービスからのレスポンスXMLや、設定ファイルXMLが
12 * 正しい形式であることを保証するために役立ちます。
13 *
14 * @param string $xmlString 検証対象となるXMLデータの文字列。
15 * @param string $xsdString 検証に使用するXSD (XML Schema Definition) データの文字列。
16 * @return bool 検証が成功した場合は true、失敗した場合は false を返します。
17 */
18function validateXmlWithSchema(string $xmlString, string $xsdString): bool
19{
20    // libxmlのエラーハンドリングを有効にし、PHPの警告を抑制します。
21    // これにより、XMLのロードやスキーマ検証でエラーが発生した場合でも、
22    // PHPが直接エラーを出さずに、libxml_get_errors()関数でエラー情報を取得できるようになります。
23    libxml_use_internal_errors(true);
24    // 既存のエラー情報をクリアします。
25    libxml_clear_errors();
26
27    // Dom\Document オブジェクトを新しく作成します。
28    // このオブジェクトはXMLドキュメントを表現し、操作するための機能を提供します。
29    $dom = new Dom\Document();
30
31    // XML文字列をDom\Documentオブジェクトにロードします。
32    // ロードに失敗した場合、たとえばXML形式が不正な場合はfalseを返します。
33    if (! $dom->loadXML($xmlString)) {
34        echo "エラー: XMLのロードに失敗しました。\n";
35        // エラーの詳細情報を取得して表示します。
36        foreach (libxml_get_errors() as $error) {
37            echo "  LIBXMLエラー: " . trim($error->message) . "\n";
38        }
39        // エラー情報をクリアして関数を終了します。
40        libxml_clear_errors();
41        return false;
42    }
43
44    // Dom\Document::schemaValidate() メソッドはファイルパスを引数として受け取るため、
45    // 提供されたXSD文字列を一時ファイルに保存する必要があります。
46    // sys_get_temp_dir() はシステムのテンポラリディレクトリのパスを返します。
47    // tempnam() は一意なファイル名を生成し、その名前で空のファイルを作成します。
48    $xsdFilename = tempnam(sys_get_temp_dir(), 'xsd_validation_');
49    if ($xsdFilename === false) {
50        echo "エラー: 一時XSDファイルの作成に失敗しました。\n";
51        libxml_clear_errors();
52        return false;
53    }
54    // XSD文字列を一時ファイルに書き込みます。
55    file_put_contents($xsdFilename, $xsdString);
56
57    // Dom\Document::schemaValidate() メソッドを呼び出して、XMLをXSDスキーマに対して検証します。
58    // 引数には、保存したXSDスキーマファイルのパスを渡します。
59    // 検証が成功すれば true、失敗すれば false が返されます。
60    $isValid = $dom->schemaValidate($xsdFilename);
61
62    // 検証結果をユーザーに表示します。
63    if ($isValid) {
64        echo "結果: XMLはXSDスキーマに対して有効です。\n";
65    } else {
66        echo "結果: XMLはXSDスキーマに対して無効です。\n";
67        // 検証エラーがある場合、その詳細情報を取得して表示します。
68        foreach (libxml_get_errors() as $error) {
69            echo "  LIBXMLエラー: " . trim($error->message) . "\n";
70        }
71    }
72
73    // 検証が完了したら、作成した一時XSDファイルを削除します。
74    // これは、不要なファイルを残さないためのクリーンアップ処理として非常に重要です。
75    unlink($xsdFilename);
76
77    // libxmlのエラー情報をクリアします。
78    libxml_clear_errors();
79    // (オプション) libxmlのエラーハンドリング設定を元の状態に戻す場合は、
80    // libxml_use_internal_errors(false); を呼び出しますが、この関数内では省略します。
81
82    return $isValid;
83}
84
85// --- 以下は、上記関数を実際に使用する例です ---
86
87// 1. 正常なXMLと、それに適合するXSDスキーマの例
88$validXml = <<<XML
89<bookstore>
90  <book category="cooking">
91    <title lang="en">Everyday Italian</title>
92    <author>Giada De Laurentiis</author>
93    <year>2005</year>
94    <price>30.00</price>
95  </book>
96</bookstore>
97XML;
98
99$sampleXsd = <<<XSD
100<?xml version="1.0" encoding="UTF-8" ?>
101<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
102
103<xs:element name="bookstore">
104  <xs:complexType>
105    <xs:sequence>
106      <xs:element name="book" maxOccurs="unbounded">
107        <xs:complexType>
108          <xs:sequence>
109            <xs:element name="title" type="xs:string"/>
110            <xs:element name="author" type="xs:string"/>
111            <xs:element name="year" type="xs:integer"/>
112            <xs:element name="price" type="xs:decimal"/>
113          </xs:sequence>
114          <xs:attribute name="category" type="xs:string" use="required"/>
115        </xs:complexType>
116      </xs:element>
117    </xs:sequence>
118  </xs:complexType>
119</xs:element>
120
121</xs:schema>
122XSD;
123
124echo "--- 正常なXMLとXSDでの検証 --- \n";
125validateXmlWithSchema($validXml, $sampleXsd);
126echo "\n"; // 結果を見やすくするための改行
127
128// 2. 不正なXMLの例 (XSDで数値型が定義されている 'price' 要素に文字列を格納)
129$invalidXml = <<<XML
130<bookstore>
131  <book category="cooking">
132    <title lang="en">Everyday Italian</title>
133    <author>Giada De Laurentiis</author>
134    <year>2005</year>
135    <price>thirty</price> <!-- ここが不正:XSDではdecimal型が期待される -->
136  </book>
137</bookstore>
138XML;
139
140echo "--- 不正なXMLとXSDでの検証 (priceが文字列) --- \n";
141validateXmlWithSchema($invalidXml, $sampleXsd);
142echo "\n";
143
144// 3. XMLがXSDに定義されていない要素を含んでいる場合
145$extraElementXml = <<<XML
146<bookstore>
147  <book category="cooking">
148    <title lang="en">Everyday Italian</title>
149    <author>Giada De Laurentiis</author>
150    <year>2005</year>
151    <price>30.00</price>
152    <currency>USD</currency> <!-- XSDに定義されていない要素 -->
153  </book>
154</bookstore>
155XML;
156
157echo "--- XMLがXSDに定義されていない要素を含んでいる場合 --- \n";
158validateXmlWithSchema($extraElementXml, $sampleXsd);
159echo "\n";

このサンプルコードは、PHP 8で導入されたDom\DocumentクラスのschemaValidateメソッドを利用し、XMLデータが特定のXSD(XML Schema Definition)スキーマに準拠しているかを検証する方法を説明しています。この機能は、WebサービスからのレスポンスXMLや設定ファイルXMLなど、受け取ったXMLデータが期待通りの構造やデータ型であるかを確認する際に非常に役立ちます。

schemaValidateメソッドは、引数として検証に使用するXSDスキーマファイルのパス(string $filename)を受け取ります。そして、検証の結果として、XMLがスキーマに適合していればtrueを、適合していなければfalseをブール値(bool)で返します。

サンプルコードでは、XSDスキーマが文字列として提供されるため、schemaValidateがファイルパスを要求する要件を満たすために、一時ファイルにXSDスキーマを書き込んでからそのパスをメソッドに渡しています。また、libxml_use_internal_errors(true)を設定することで、XMLのロードやスキーマ検証で発生したエラーを内部的に捕捉し、libxml_get_errors()関数で詳細なエラーメッセージを取得・表示しています。検証が完了した後には、一時ファイルを適切に削除し、システムのリソースをクリーンアップする処理も含まれています。この一連の処理により、XMLデータの整合性を効率的にチェックできます。

Dom\Document::schemaValidateメソッドはPHP 8以降で利用され、XMLデータをXSDスキーマに対して検証します。このメソッドはXSDスキーマの「ファイルパス」を引数として受け取るため、スキーマが文字列で与えられる場合は一時ファイルに保存し、検証完了後には必ずその一時ファイルを削除する処理が必要です。一時ファイルの削除漏れは、ディスク容量の消費やセキュリティリスクにつながる可能性がありますので注意しましょう。また、XMLのロードやスキーマ検証でエラーが発生した場合に備え、libxml_use_internal_errors(true)を設定し、libxml_get_errors()で詳細なエラー情報を取得して適切に処理することが重要です。これにより、検証が失敗した具体的な原因を把握できます。

関連コンテンツ

関連プログラミング言語