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で出力されます。
エラー理由をうまくキャッチして、その後の分岐に活かすとかそういうことはできるのでしょうか…その辺はまたこんど調べてみようと思います。。
