【PHP8.x】Dom\HTMLDocument::schemaValidateSource()メソッドの使い方
schemaValidateSourceメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
schemaValidateSourceメソッドは、Dom\HTMLDocumentオブジェクトが読み込んだHTMLドキュメントの内容が、指定されたスキーマに適合しているかを検証するメソッドです。
ここで言う「スキーマ」とは、HTMLやXMLなどの構造化された文書が、どのような要素や属性を持つべきか、そしてそれらがどのように配置されるべきかといった、構造に関するルールを定義したものです。このメソッドは、HTMLドキュメントがこれらのルールに沿って記述されているかを確認します。
このメソッドを利用することで、例えば、ウェブページがHTML5の厳密な仕様に準拠しているか、あるいは特定のアプリケーションで定義されたカスタムルールに適合しているかなどをプログラム上でチェックできます。これにより、ウェブアプリケーションが生成するHTMLが常に正しい構造を持っていることを保証し、ブラウザでの予期せぬ表示エラーやスクリプトの誤動作を防ぐのに役立ちます。
メソッドの引数には、検証に使用するスキーマのファイルパスやURI(Uniform Resource Identifier)を指定します。検証が成功し、ドキュメントがスキーマに適合している場合はtrueを、適合していない場合はfalseを返します。検証プロセス中に発生したエラーについては、PHPのlibxmlエラーハンドリング機能を通じて詳細な情報を取得することが可能です。この機能は、特に大規模なシステムにおいて、HTMLの品質管理とデバッグ作業を効率化するために重要です。
構文(syntax)
1<?php 2 3$document = new Dom\HTMLDocument(); 4$schemaXmlSource = '<!-- XSDスキーマのXML文字列をここに記述 -->'; 5$isValid = $document->schemaValidateSource($schemaXmlSource); 6 7?>
引数(parameters)
string $source, int $flags = 0
- string $source: 検証するHTMLソースコードを指定する文字列
- int $flags = 0: 検証時の動作を制御するフラグを指定する整数 (デフォルトは0で、フラグなし)
戻り値(return)
bool
このメソッドは、HTMLドキュメントがXMLスキーマに対して有効であるかどうかを示す真偽値(bool)を返します。有効な場合はtrue、無効な場合はfalseが返されます。
サンプルコード
PHP: Dom\HTMLDocument::schemaValidateSource でHTML構造をXSD検証する
1<?php 2 3/** 4 * Dom\HTMLDocument::schemaValidateSource メソッドの使用例 5 * 6 * この関数は、指定されたHTMLコンテンツがXMLスキーマ定義 (XSD) に準拠しているかを検証します。 7 * Dom\HTMLDocument はHTMLを扱いますが、schemaValidateSource メソッドはドキュメントの 8 * XML構造を検証します。この例では、HTMLドキュメント内に存在する特定のカスタム要素の構造を 9 * 検証するシンプルなXSDを適用します。 10 * 11 * HTML5は通常XMLとして厳格ではないため、このメソッドは、XHTMLのようにXMLとして整形式なHTML、 12 * またはXML名前空間を持つ特定のカスタム要素の検証に適しています。 13 * 14 * @param string $htmlContent 検証対象のHTMLコンテンツ 15 * @param string $xsdSource 検証に使用するXMLスキーマ定義 (XSD) 文字列 16 * @param string $caseDescription このテストケースの説明 17 * @return bool 検証が成功した場合は true、失敗した場合は false 18 */ 19function validateHtmlStructureWithSchema(string $htmlContent, string $xsdSource, string $caseDescription): bool 20{ 21 // libxmlのエラーを内部で捕捉するように設定し、既存のエラーをクリアします。 22 // これにより、schemaValidateSourceからの詳細なエラーメッセージを取得できます。 23 libxml_clear_errors(); 24 libxml_use_internal_errors(true); 25 26 echo "--- {$caseDescription} ---\n"; 27 28 // Dom\HTMLDocument インスタンスを作成します。 29 // これはHTML5を扱うためのDOMオブジェクトです。 30 $document = new Dom\HTMLDocument(); 31 32 // HTMLコンテンツをロードします。 33 // ロード中にHTMLパースエラーが発生することがありますが、 34 // ここではschemaValidateSourceの検証エラーに焦点を当てます。 35 $document->loadHTML($htmlContent); 36 37 echo "HTMLコンテンツをロードしました。\n"; 38 39 // ドキュメントをスキーマに対して検証します。 40 // schemaValidateSourceは、ロードされたHTMLのDOMツリーがXSDに準拠しているかをチェックします。 41 $isValid = $document->schemaValidateSource($xsdSource); 42 43 if ($isValid) { 44 echo "結果: 検証に成功しました。\n"; 45 } else { 46 echo "結果: 検証に失敗しました。\n"; 47 // 検証失敗時にlibxmlが生成したエラーの詳細を表示します。 48 foreach (libxml_get_errors() as $error) { 49 echo sprintf( 50 " Libxml Error (Code: %d, Level: %d, Line: %d): %s\n", 51 $error->code, 52 $error->level, 53 $error->line, 54 trim($error->message) 55 ); 56 } 57 } 58 libxml_clear_errors(); // 各ケースの後にエラーをクリアします。 59 echo "\n"; // 各ケースの終わりに改行を追加します。 60 return $isValid; 61} 62 63// 検証に使用するシンプルなXMLスキーマ (XSD) 64// このスキーマは、HTMLドキュメントの<body>内にXML名前空間を持つ<my-message>要素が 65// 必須であることを定義します。 66// HTMLの他の要素については、xs:any を使用して寛容に扱います。 67$schema = <<<'XSD' 68<?xml version="1.0" encoding="UTF-8"?> 69<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 70 targetNamespace="http://example.com/my-html-ns" 71 xmlns="http://example.com/my-html-ns" 72 elementFormDefault="qualified"> 73 74 <!-- ルートのhtml要素は、どんな内容でも許容するように緩く定義 --> 75 <xs:element name="html"> 76 <xs:complexType mixed="true"> 77 <xs:sequence> 78 <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> 79 </xs:sequence> 80 </xs:complexType> 81 </xs:element> 82 83 <!-- body要素は、my-message要素を1つだけ含むことを必須とします --> 84 <xs:element name="body"> 85 <xs:complexType mixed="true"> 86 <xs:sequence> 87 <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> 88 <xs:element name="my-message" type="xs:string"/> 89 <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> 90 </xs:sequence> 91 </xs:complexType> 92 </xs:element> 93 94 <!-- my-message要素の定義 --> 95 <xs:element name="my-message" type="xs:string"/> 96 97</xs:schema> 98XSD; 99 100 101// --- 検証に成功するHTMLコンテンツの例 --- 102// my-message要素がXSDで定義された名前空間を持ち、<body>内に存在します。 103$validHtml = <<<'HTML' 104<!DOCTYPE html> 105<html> 106<head><title>Success Case</title></head> 107<body> 108 <h1>Welcome</h1> 109 <my-message xmlns="http://example.com/my-html-ns">Hello Schema Validation!</my-message> 110 <p>This document is valid according to the schema.</p> 111</body> 112</html> 113HTML; 114validateHtmlStructureWithSchema($validHtml, $schema, "検証成功ケース (my-message要素が存在し、名前空間も一致)"); 115 116 117// --- 検証に失敗するHTMLコンテンツの例 (my-message要素がない) --- 118// body要素内に必須のmy-message要素がありません。 119$invalidHtmlMissingElement = <<<'HTML' 120<!DOCTYPE html> 121<html> 122<head><title>Failure Case</title></head> 123<body> 124 <h1>Welcome</h1> 125 <p>This document is missing the required my-message element.</p> 126</body> 127</html> 128HTML; 129validateHtmlStructureWithSchema($invalidHtmlMissingElement, $schema, "検証失敗ケース (my-message要素がない)"); 130 131 132// --- 検証に失敗するHTMLコンテンツの例 (my-message要素の名前空間が異なる) --- 133// my-message要素は存在するものの、XSDで指定された名前空間と一致しません。 134$invalidHtmlWrongNamespace = <<<'HTML' 135<!DOCTYPE html> 136<html> 137<head><title>Wrong Namespace Case</title></head> 138<body> 139 <h1>Welcome</h1> 140 <my-message xmlns="http://wrong.example.com/ns">Hello Schema Validation!</my-message> 141 <p>This document has a my-message element but with a different namespace.</p> 142</body> 143</html> 144HTML; 145validateHtmlStructureWithSchema($invalidHtmlWrongNamespace, $schema, "検証失敗ケース (my-message要素の名前空間がXSDと異なる)"); 146 147 148// libxmlのエラー捕捉設定を元の状態に戻します。 149libxml_use_internal_errors(false); 150
PHPのDom\HTMLDocument::schemaValidateSourceメソッドは、指定されたHTMLドキュメントがXMLスキーマ定義(XSD)に準拠しているかを確認するための機能です。このメソッドはDom\HTMLDocumentクラスのインスタンスから呼び出され、ロードされたHTMLコンテンツのXML構造が、提供されたXSDと一致するかを検証します。
このメソッドは、第一引数に検証に使用するXSDの文字列(string $source)を、第二引数にオプションのフラグ(int $flags = 0)を受け取ります。検証が成功した場合は真(true)、失敗した場合は偽(false)を戻り値(bool型)として返します。
サンプルコードでは、まずDom\HTMLDocumentインスタンスを作成し、検証したいHTMLコンテンツをロードしています。その後、schemaValidateSourceメソッドに、特定のカスタム要素の構造を定義したXSDの文字列を渡して検証を実行します。HTML5はXMLほど厳格ではないため、このメソッドは、XHTMLのようなXMLとして整形式なHTMLや、XML名前空間を持つカスタム要素の構造を厳密にチェックしたい場合に特に役立ちます。検証が失敗した際には、libxml_get_errors()関数を使用することで、具体的なエラー情報を取得し、どの部分がXSDに準拠していないかを特定できます。
schemaValidateSourceメソッドはHTMLドキュメントのXMLスキーマ検証に利用しますが、HTML5はXMLとして厳格ではないため、XHTMLやXML名前空間を持つカスタム要素の検証に適しています。HTML全体の構造ではなく、特定のXML要素の構造ルールを定義したXSD文字列を引数に渡して検証します。検証に失敗した際は、libxml_use_internal_errors(true)を設定し、libxml_get_errors()で詳細なエラー情報を取得できます。XSDで定義する要素の名前空間と、HTMLドキュメント内の要素の名前空間が一致しないと検証は失敗しますので、この点に特に注意してください。
Dom\HTMLDocument::schemaValidateSource によるHTMLスキーマ検証
1<?php 2 3// Dom\HTMLDocument::schemaValidateSource メソッドの使用例 4// HTMLドキュメントを指定されたスキーマ文字列に対して検証します。 5// このメソッドは、DOMドキュメントの構造が、与えられたスキーマ(例: DTDやXML Schema)の定義に 6// 準拠しているかどうかをブール値 (true/false) で返します。 7 8/** 9 * libxml_get_errors() から取得したエラー情報を表示し、クリアするヘルパー関数。 10 */ 11function displayLibxmlErrors(): void 12{ 13 $errors = libxml_get_errors(); 14 if (!empty($errors)) { 15 echo " <詳細なエラー情報>:\n"; 16 foreach ($errors as $error) { 17 // エラーメッセージは改行を含むことがあるため、そのまま出力します。 18 echo " - メッセージ: {$error->message}"; 19 echo " 行: {$error->line}, カラム: {$error->column}, コード: {$error->code}\n"; 20 } 21 libxml_clear_errors(); // 次の検証に影響を与えないよう、エラーをクリアします。 22 } else { 23 echo " (LibXMLからエラー情報は報告されませんでした。)\n"; 24 } 25} 26 27// ----------------------------------------------------------- 28// 1. スキーマに準拠する有効なHTMLの検証例 29// ----------------------------------------------------------- 30 31echo "--- 有効なHTMLとスキーマの検証例 ---\n"; 32 33// 検証対象のシンプルなHTML文字列。 34// ここでは、カスタムの <item> 要素を含む構造を例としています。 35$validHtmlContent = <<<'HTML' 36<!DOCTYPE html> 37<html> 38<body> 39 <item> 40 <name>商品A</name> 41 <price>100</price> 42 </item> 43</body> 44</html> 45HTML; 46 47// 検証に使用するDTDスキーマ文字列。 48// <body>内に少なくとも1つの<item>があり、<item>内に<name>と<price>が 49// この順序で含まれることを定義しています。 50$validSchemaSource = <<<'DTD' 51<!ELEMENT html (body)> 52<!ELEMENT body (item+)> 53<!ELEMENT item (name, price)> 54<!ELEMENT name (#PCDATA)> 55<!ELEMENT price (#PCDATA)> 56DTD; 57 58// Dom\HTMLDocument オブジェクトを作成します。 59$documentValid = new Dom\HTMLDocument(); 60 61// HTMLをDOMドキュメントに読み込みます。 62// libxml_use_internal_errors を使うことで、HTMLパース時の警告などを抑制し、 63// schemaValidateSource の検証結果にのみ注目できるようにします。 64libxml_use_internal_errors(true); 65$documentValid->loadHTML($validHtmlContent); 66libxml_use_internal_errors(false); 67 68// ドキュメントに対してスキーマ検証を実行します。 69// 第一引数にスキーマ文字列を渡し、戻り値の bool を確認します。 70$isValid = $documentValid->schemaValidateSource($validSchemaSource); 71 72if ($isValid) { 73 echo "✔ HTMLドキュメントはスキーマに対して有効です。\n"; 74} else { 75 echo "✖ HTMLドキュメントはスキーマに対して無効です。\n"; 76 displayLibxmlErrors(); // エラーの詳細を表示します。 77} 78 79// ----------------------------------------------------------- 80// 2. スキーマに準拠しない無効なHTMLの検証例 81// ----------------------------------------------------------- 82 83echo "\n--- 無効なHTMLとスキーマの検証例 ---\n"; 84 85// 検証対象の無効なHTML文字列。 86// スキーマで定義されていない <description> タグが <item> 内に含まれています。 87$invalidHtmlContent = <<<'HTML' 88<!DOCTYPE html> 89<html> 90<body> 91 <item> 92 <name>商品B</name> 93 <price>200</price> 94 <description>これは商品の説明です。</description> <!-- スキーマでは許可されていません --> 95 </item> 96</body> 97</html> 98HTML; 99 100// 同じDTDスキーマを使用します。 101// <description>タグはスキーマで許可されていないため、このHTMLは無効と判断されます。 102$invalidSchemaSource = $validSchemaSource; 103 104// Dom\HTMLDocument オブジェクトを作成します。 105$documentInvalid = new Dom\HTMLDocument(); 106 107// HTMLをDOMドキュメントに読み込みます。 108libxml_use_internal_errors(true); 109$documentInvalid->loadHTML($invalidHtmlContent); 110libxml_use_internal_errors(false); 111 112// ドキュメントに対してスキーマ検証を実行します。 113$isInvalid = $documentInvalid->schemaValidateSource($invalidSchemaSource); 114 115if ($isInvalid) { 116 echo "✖ HTMLドキュメントはスキーマに対して有効です。(予期せぬ結果)\n"; 117 displayLibxmlErrors(); 118} else { 119 echo "✔ HTMLドキュメントはスキーマに対して無効です。(期待通り)\n"; 120 displayLibxmlErrors(); // エラーの詳細を表示します。 121} 122
Dom\HTMLDocument::schemaValidateSourceメソッドは、PHPのDom\HTMLDocumentオブジェクトに読み込まれたHTMLドキュメントが、指定されたスキーマ文字列に準拠しているかを検証します。
引数$sourceには、HTMLの構造を定義するスキーマの文字列(例:DTDやXML Schema)を渡します。第二引数$flagsはオプションで、検証動作を調整する整数値ですが、通常は0を指定します。
このメソッドは検証結果をbool型で返します。HTMLがスキーマのルールに完全に適合していればtrue、一つでも違反があればfalseです。falseが返された場合、libxml_get_errors()関数を使用することで、具体的なエラー情報を取得できます。
サンプルコードは、スキーマに適合する有効なHTMLがtrueを返す例と、適合しない無効なHTMLがfalseを返し、そのエラー情報も確認できる例を示しています。この機能は、HTMLコンテンツの構造がプログラムの期待通りかをチェックし、ウェブアプリケーションの品質維持に役立ちます。
このメソッドは、指定されたスキーマ文字列に対してHTMLドキュメントの構造が準拠しているかを検証し、結果を真偽値で返します。検証が失敗しfalseが返された場合、libxml_get_errors()を使って詳細なエラー情報を確認することが非常に重要です。サンプルコードのように、libxml_use_internal_errors(true)を利用して内部エラーを有効にすると、loadHTMLなどの処理中に発生する警告と検証エラーを区別しやすくなります。ただし、検証後にはlibxml_clear_errors()でエラーキューを必ずクリアしてください。スキーマ(DTDやXML Schemaなど)の定義が不正確だと、正しく検証できないため、スキーマの内容を正確に記述することも求められます。