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