[php] XSDを使ってXMLが正しいかvalidationをする方法

phpを使ってXMLのスキーマバリデーションってできるのだろうか?ということで調べました。DOMDocumentというクラスを使うことで対処可能でした。

XSDってなんですか?

XSDというのは、XMLの構造を定義した文書です。
このXSD(スキーマ)に照らして、XMLが正しいかどうかを検証する作業がバリデーションです。このバリデーションを利用することで、想定しない構造をしているXML文書を弾くことが可能になります。

PHPでスキーマバリデーション

PHPでスキーマバリデーションを利用するには、DOMDocumentというクラスを利用します。
PHPでXMLを扱うには2つ方法があって、simpleXMLとDOMDocumentがあるんですが、そのうちの複雑な方ということになります。

実際にバリデーションする際のコードは以下のようになります。

<?php
	
	$dom = new DOMDocument();
	$dom->encoding = 'UTF-8';

	$xmlFileName = "sample.xml";
	$xmlData = file_get_contents($xmlFileName);
	$dom->loadXML($xmlData, LIBXML_NOBLANKS);
	
	$xsdFileName = "sample.xsd";
	
	if (!$dom->schemaValidate( $xsdFileName ))
	{
		print("NG");
	}
	else
	{
		print("OK");
	}

?>

上記の例だと、バリデーションの対象となるXMLがsample.xmlというファイルの内容で、これの構造を定義したXSDファイルがsample.xsdというファイルになります。
DOMDocumentに対して、load関数でXMLを読み込んでおいて、schemaValidate関数でXSDを指定して、判定ってかんじですね。
バリデーションの結果、XMLがXSD通りの構造をしていればtrueが、XSDに反した構造になっていればfalseが返ってくるという感じです。

XSDのエラー

以下のようなエラーが出ている場合、正しくバリデーションができていません。

Warning: DOMDocument::schemaValidate(): Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'type': References from this schema to components in no namespace are not allowed, since not indicated by an import statement. in /var/www/html/.../schema.php on line 11

このエラーが言っている内容は直接はよくわかりませんが、とりあえず、こういう感じのエラーがたくさん出ている場合には、バリデーションが正常に行われていません。

この場合は、XSDの冒頭で以下のような定義が抜けています。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="https://tazakazushi.net/sample"
           xmlns="https://tazakazushi.net/sample"
           elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0.0">

3行目のxmlns=っていう部分です。デフォルトのnamespaceを指定してあげる文?みたいです。ちなみに、これはtargetNamespaceと同じ値にしておけば問題なさそうです。

おしまい

以上で無事にバリデーションができます。ちなみに、バリデーションに失敗した場合、エラー理由はWarningで出力されます。
エラー理由をうまくキャッチして、その後の分岐に活かすとかそういうことはできるのでしょうか…その辺はまたこんど調べてみようと思います。。

タイトルとURLをコピーしました