【PHP8.x】XMLReader::isValid()メソッドの使い方
isValidメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
isValidメソッドは、XMLReaderオブジェクトが現在読み込んでいるXMLドキュメントが、事前に定義されたDTD(文書型定義)やXML Schemaといった、決められたルールに準拠しているかどうかを検証し、その有効性を確認するメソッドです。このメソッドは、XMLの構造が正しいだけでなく、特定の要素の並びや属性の値の型など、より詳細な規約に沿っているかをプログラム的に検査する際に利用されます。
isValidメソッドが期待通りに機能するためには、XMLReader::setParserProperty()メソッドを用いてXMLReader::VALIDATEプロパティをtrueに設定し、バリデーション(検証)機能を有効にしておく必要があります。バリデーションが有効な状態で、XMLドキュメントが指定されたルールに準拠していればtrueを、準拠していない場合や処理中にXMLの解析エラーが発生した場合はfalseを返します。もしバリデーション機能が有効になっていない場合、このメソッドは常にtrueを返しますので注意が必要です。これにより、アプリケーションが処理すべきXMLデータが、あらかじめ想定した形式や内容であるかを確実にチェックし、不正なデータが原因で発生する問題を未然に防ぐのに役立ちます。
構文(syntax)
1<?php 2$reader = new XMLReader(); 3$reader->xml('<root></root>'); 4$isDocumentValid = $reader->isValid();
引数(parameters)
引数なし
引数はありません
戻り値(return)
bool
XMLReader::isValid() メソッドは、現在の XML ドキュメントが有効かどうかを示す真偽値 (bool) を返します。ドキュメントが有効な場合は true、無効な場合は false を返します。
サンプルコード
XMLReader::isValid でXML妥当性検証する
1<?php 2 3/** 4 * XMLReader::isValid メソッドの使用例。 5 * XML Schema (XSD) を用いてXMLの妥当性検証を行い、その結果を表示します。 6 * XSDで日付型を定義することで、特定のデータ型(この場合は日付)の妥当性チェックに関連付けます。 7 * 8 * @param string $xmlString 検証対象のXML文字列。 9 * @param string $xsdString 検証に用いるXML Schema (XSD) 文字列。 10 * @return void 11 */ 12function demonstrateXmlReaderIsValidWithXsd(string $xmlString, string $xsdString): void 13{ 14 echo "--- 検証対象のXML ---" . PHP_EOL; 15 echo $xmlString . PHP_EOL . PHP_EOL; 16 17 // libxmlのエラーを内部で処理し、エラー情報を取得できるように設定 18 libxml_use_internal_errors(true); 19 libxml_clear_errors(); // 前回の実行で残ったエラーをクリア 20 21 $reader = new XMLReader(); 22 23 // XML文字列を読み込み 24 if (!$reader->xml($xmlString)) { 25 echo "エラー: XML文字列の読み込みに失敗しました。" . PHP_EOL; 26 libxml_clear_errors(); // エラー情報をクリア 27 return; 28 } 29 30 // XMLReader::setSchema() はファイルパスを引数に取るため、 31 // XSD文字列を一時ファイルに書き出します。 32 $xsdFilePath = tempnam(sys_get_temp_dir(), 'xsd_'); 33 if ($xsdFilePath === false) { 34 echo "エラー: 一時XSDファイルの作成に失敗しました。" . PHP_EOL; 35 $reader->close(); 36 libxml_clear_errors(); 37 return; 38 } 39 file_put_contents($xsdFilePath, $xsdString); 40 41 // XMLReaderにXSDスキーマを設定 42 if (!$reader->setSchema($xsdFilePath)) { 43 echo "エラー: XSDスキーマの設定に失敗しました。" . PHP_EOL; 44 unlink($xsdFilePath); // 一時ファイルを削除 45 $reader->close(); 46 libxml_clear_errors(); 47 return; 48 } 49 50 // 妥当性検証を有効化 51 // この設定により、DTDやXSDスキーマに基づく検証が行われます。 52 $reader->setParserProperty(XMLReader::VALIDATE, true); 53 54 echo "XSDスキーマに基づきXMLの妥当性検証を開始します..." . PHP_EOL; 55 56 // XMLドキュメント全体を読み進める 57 // isValid() はドキュメント全体を読み込んだ後に、最終的な妥当性を判断します。 58 while ($reader->read()) { 59 // ここでXMLノードの具体的な処理を行うこともできますが、 60 // isValid() メソッドのデモンストレーションのため省略します。 61 } 62 63 // ドキュメント全体がXSDスキーマに対して妥当であるかを確認 64 if ($reader->isValid()) { 65 echo "結果: XMLは妥当です。" . PHP_EOL; 66 } else { 67 echo "結果: XMLは妥当ではありません。" . PHP_EOL; 68 echo "--- 妥当性検証エラー詳細 ---" . PHP_EOL; 69 // libxml_get_errors() で妥当性検証の詳細なエラー情報を取得 70 foreach (libxml_get_errors() as $error) { 71 echo "行 " . $error->line . ": " . trim($error->message) . PHP_EOL; 72 } 73 } 74 75 // 後処理: リーダーを閉じ、一時ファイルを削除し、エラー設定を元に戻す 76 $reader->close(); 77 unlink($xsdFilePath); // 作成した一時ファイルを削除 78 libxml_clear_errors(); 79 libxml_use_internal_errors(false); // libxmlのエラー設定をデフォルトに戻す 80 echo PHP_EOL; 81} 82 83// ----------------------------------------------------------------------------- 84// サンプル実行 85// ----------------------------------------------------------------------------- 86 87// 日付型 (xs:date) を含むXML構造を定義するXSDスキーマ 88// <date>要素は YYYY-MM-DD 形式を要求します。 89$xsdSchema = <<<XSD 90<?xml version="1.0" encoding="UTF-8"?> 91<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 92 <xs:element name="record"> 93 <xs:complexType> 94 <xs:sequence> 95 <xs:element name="date" type="xs:date"/> <!-- YYYY-MM-DD 形式の日付を要求 --> 96 <xs:element name="message" type="xs:string"/> 97 </xs:sequence> 98 </xs:complexType> 99 </xs:element> 100</xs:schema> 101XSD; 102 103// --- 妥当なXMLの例 --- 104// XSDスキーマの要件(date要素がxs:date型、message要素がxs:string型)を満たしています。 105$validXml = <<<XML 106<?xml version="1.0" encoding="UTF-8"?> 107<record> 108 <date>2023-10-27</date> 109 <message>このXMLは正しい日付フォーマットと構造を持っています。</message> 110</record> 111XML; 112 113demonstrateXmlReaderIsValidWithXsd($validXml, $xsdSchema); 114 115// --- 妥当でないXMLの例 (日付フォーマットが不正) --- 116// <date>要素の内容がxs:date型 (YYYY-MM-DD) に従っていません (YYYY/MM/DD 形式)。 117$invalidXmlDateFormat = <<<XML 118<?xml version="1.0" encoding="UTF-8"?> 119<record> 120 <date>2023/10/27</date> <!-- 不正な日付フォーマット (YYYY/MM/DD) --> 121 <message>このXMLは不正な日付フォーマットを含んでいます。</message> 122</record> 123XML; 124 125demonstrateXmlReaderIsValidWithXsd($invalidXmlDateFormat, $xsdSchema); 126 127// --- 妥当でないXMLの例 (必須要素が欠落) --- 128// XSDスキーマで必須とされている <date> 要素が欠落しています。 129$invalidXmlMissingElement = <<<XML 130<?xml version="1.0" encoding="UTF-8"?> 131<record> 132 <message>このXMLは必須のdate要素が欠落しています。</message> 133</record> 134XML; 135 136demonstrateXmlReaderIsValidWithXsd($invalidXmlMissingElement, $xsdSchema);
PHP 8のXMLReader::isValidメソッドは、XML文書が事前に定義されたXML Schema (XSD) に従って正しい構造とデータ型を持っているかを確認するために使用されます。システムエンジニアにとって、外部から受け取ったXMLデータが期待通りの形式であるかをプログラムで検証する際に非常に重要な機能です。
このメソッドは引数を取りません。XMLReaderオブジェクトがsetSchema()でXSDスキーマを設定され、かつsetParserProperty(XMLReader::VALIDATE, true)で妥当性検証が有効にされている状態で、XML文書全体を読み込んだ後にその妥当性を判断します。戻り値はbool型で、XMLがスキーマに適合し妥当であればtrue、そうでなければfalseを返します。
サンプルコードでは、まずXMLReaderにXML文字列とXSDスキーマを設定し、妥当性検証を有効化しています。XSDスキーマでは、<date>要素をxs:date型として定義しており、これによりYYYY-MM-DD形式の日付のみを許可するよう制約を設けています。while($reader->read())でXML文書全体を走査した後、isValid()が実行されます。もし2023/10/27のような不正な日付フォーマットや、XSDで必須とされている要素が欠落していた場合、isValid()はfalseを返します。このとき、libxml_get_errors()関数を使用することで、具体的な検証エラーの内容や発生行数などを取得し、原因を特定することができます。この機能は、XMLデータの品質を保証し、システム連携におけるエラーを未然に防ぐために役立ちます。
XMLReader::isValidメソッドは、XML Schema(XSD)を用いてXMLの構造や日付フォーマットなどのデータ型の妥当性を検証できます。利用には、XMLReader::setSchema()でXSDを設定し、XMLReader::setParserProperty(XMLReader::VALIDATE, true)で検証を有効にする必要があります。isValid()は、while ($reader->read())でXMLドキュメント全体を読み込み終えた後に呼び出す点に注意してください。XSD文字列は一時ファイルとして保存してsetSchema()に渡し、処理後は必ずファイルを削除しましょう。また、libxml_use_internal_errors(true)で内部エラーを捕捉し、libxml_get_errors()で詳細を確認できますが、使用後は$reader->close()でリソースを解放し、libxml_use_internal_errors(false)で設定を元に戻すのを忘れないでください。
PHP XMLReader::isValidでDTD検証する
1<?php 2 3/** 4 * XMLReader を使用して、XML文字列が内部DTDに準拠しているかを検証します。 5 * 6 * この関数は、XMLReader を初期化し、DTD検証を有効にしてXML文字列を解析します。 7 * XMLReader::isValid() メソッドは、文書がそのDTDの規則に適合しているかどうかを 8 * 最終的に報告します。これはXMLの構造的整合性を確認するものであり、 9 * 特定のデータ形式(例:メールアドレスの書式)の検証は行いません。 10 * 11 * @param string $xmlContent 検証するXML文字列。 12 * @return bool XMLがDTDに従って有効であれば true、そうでなければ false を返します。 13 */ 14function validateXmlStringAgainstDtd(string $xmlContent): bool 15{ 16 $reader = new XMLReader(); 17 18 // XML文字列を開きます。オープンに失敗した場合は即座に false を返します。 19 // これは、XMLが根本的にMalformedな場合に発生する可能性があります。 20 if (!$reader->XML($xmlContent)) { 21 return false; 22 } 23 24 // DTD検証を有効にします。これにより、XMLReaderはDTDの規則に基づいて 25 // 文書を解析しながら検証を行います。 26 $reader->setParserProperty(XMLReader::VALIDATE, true); 27 28 // 文書全体を読み込み、検証プロセスをトリガーします。 29 // isValid() の結果は、通常、文書の全体が読み込まれた後に信頼できるものとなります。 30 while ($reader->read()) { 31 // ここでは特定のノード処理は行わず、解析を進めることのみを目的とします。 32 } 33 34 // 文書の解析後、isValid() はDTDに対する検証結果を返します。 35 $isValid = $reader->isValid(); 36 37 // XMLReader を閉じ、リソースを解放します。 38 $reader->close(); 39 40 return $isValid; 41} 42 43// --- 使用例 --- 44 45// DTDに準拠した有効なXML文字列の例 46// user要素はnameとemail要素をこの順序で持つ必要があります。 47$validXml = <<<XML 48<?xml version="1.0" encoding="UTF-8"?> 49<!DOCTYPE user [ 50 <!ELEMENT user (name, email)> 51 <!ELEMENT name (#PCDATA)> 52 <!ELEMENT email (#PCDATA)> 53]> 54<user> 55 <name>Alice Smith</name> 56 <email>alice.smith@example.com</email> 57</user> 58XML; 59 60// DTDに準拠しない無効なXML文字列の例 (email要素が欠落) 61// DTDではemail要素が必須とされていますが、このXMLには存在しません。 62$invalidXml = <<<XML 63<?xml version="1.0" encoding="UTF-8"?> 64<!DOCTYPE user [ 65 <!ELEMENT user (name, email)> 66 <!ELEMENT name (#PCDATA)> 67 <!ELEMENT email (#PCDATA)> 68]> 69<user> 70 <name>Bob Johnson</name> 71 <!-- email要素がここにありません。 --> 72</user> 73XML; 74 75// 有効なXML文字列を検証し、結果を出力します。 76echo "有効なXMLの結果: "; 77var_dump(validateXmlStringAgainstDtd($validXml)); // 期待値: true 78 79// 無効なXML文字列を検証し、結果を出力します。 80echo "無効なXMLの結果: "; 81var_dump(validateXmlStringAgainstDtd($invalidXml)); // 期待値: false
PHP 8のXMLReader::isValid()メソッドは、XML文書がその内部DTD(Document Type Definition)に構造的に準拠しているかを検証するために使用されます。このメソッド自体は引数をとりませんが、XMLReaderオブジェクトが文書全体を読み込んだ後に、DTDの規則に沿っているかを真偽値(trueまたはfalse)で返します。
提供されたサンプルコードでは、validateXmlStringAgainstDtd関数内でXMLReaderを初期化し、setParserProperty(XMLReader::VALIDATE, true)でDTD検証を有効にしています。その後、while ($reader->read())でXML文書全体を解析することで検証プロセスをトリガーし、最後にisValid()を呼び出して検証結果を取得しています。例えば、DTDで特定の要素が必須とされているにもかかわらず、XML文書内でその要素が欠けている場合、isValid()はfalseを返します。
重要な点として、XMLReader::isValid()はXML文書の構造がDTDに適合しているかを確認するものであり、「php isvalidemail」というキーワードが示すような、メールアドレスの書式など特定のデータ内容の正当性まで検証する機能はありません。これはあくまでXML文書の構造的な整合性を確認するためのメソッドです。
XMLReader::isValid()メソッドは、XML文書がその内部DTD(文書型定義)に構造的に準拠しているかを検証する機能を提供します。これは、キーワードにあるような「メールアドレスの書式検証」など、特定のデータ内容の正当性や外部データベースとの照合を行うものではありませんのでご注意ください。
このメソッドを正しく利用するためには、まずsetParserProperty(XMLReader::VALIDATE, true)でDTD検証を明示的に有効にする必要があります。また、isValid()が信頼できる結果を返すのは、read()メソッドでXML文書全体が読み込まれ、解析が完了した後です。処理後は、close()メソッドを呼び出してリソースを適切に解放することを忘れないでください。DTD自体の記述にもXML構造に関する知識が必要となります。