シリーズJAVAのフォーマット変換は、その4で終わりにしようと思ったんだけど、ちょっとこのまえ、ぼーっとしてたら、「XMLのバリデーションが」・・「DOMで。。。」とかいうのが聞こえたんで、ま、これも、天の声?ということで、バリデーションについてかきましょうかね。。
ってことで、今回はバリデーション。
■バリデーションには、2種類ある
JAVAのDOMで、バリデーションというと、
(1)DocumentBuilderFactoryのsetValidatingメソッドをtrueにするもの
(2)Java1.からはいった、Validatorクラスのvalidateメソッドでやるもの
と2種類ある。
このうち、(1)は、開始タグがあって、終了タグがないというのもはないか?とか、ちゃんと入れ子になっているかとか、そーいう、スキーマがなくてもできるチェックを行っている。
一方、(2)は、XMLスキーマを読み込んで、スキーマに基づき、このタグのあとに、このタグが着ているかどうか?をチェックするものなのら。
なので、(1)は、スキーマがなくてもできるし、Java1.4でも、できる。
■Java1.4以前の場合、ノートパッドでUTF-8のXMLを修正した場合の注意
ただし、Java1.4でXMLを扱う場合、注意が必要になる
以下の操作をすると、エラーになる
・機械的に、UTF8で出力したXMLファイルをノートパッドで開き、
・修正するかどうかにかかわらず、保存し
・Javaで読み込むとエラーになる。
理由は、ノートパッドを使って、UTF-8で保存した場合、ファイルの先頭に、UTF8を示すマークをつける。一般にWindows2000以上では、このマークは見えない(たしか98のノートパッドでは見えたと思った)。多くのアプリケーションでは、このコードは読み飛ばすが、Java1.4のパーサーは読み飛ばさない。その結果、このコードに引っかかり、エラーとなる。
対策は。。。素直にJava1.5を使うことだ。XMLの場合、1.5のほうが、バリデーションとかもはいってて、いいぞお(^^)v。。。。かあ(^^;)
ただし、1.4ではバリデーションでエラーが出なかったのに、1.5になったとたんにエラーになるものがある・・よくわかんないんだ、これ??
■まず、XMLスキーマを作ることだが。。。
では、XMLスキーマとXMLファイルを作ることだが、これは、Access2003を使って、
エクスポートするとつくれる。
ファイルの種類をXMLにして、保存すると、
スキーマつきかどうかをチェックできるので、
スキーマもつける。
すると、拡張子xsdのファイルもできる。
■方法の概要
「(1)DocumentBuilderFactoryのsetValidatingメソッドをtrueにするもの」は、
そのとおりにやってくれ。それ以上の説明は要らないと思う。
(わからなかったらしたのソースを参照。dbfactory.setValidating(true);がそれにあたる)。
「(2)Java1.からはいった、Validatorクラスのvalidateメソッドでやるもの」は、
以下の手順で行う
・SchemaFactoryを生成する(SchemaFactory.newInstanceで)
・スキーマファイルを読み込み、StreamSourceを生成させる
・スキーマをnewSchemaする
・Validatorをつくる
・validator.validateする(引数が、読みこんだXMLのDomのDOMSourceとなる)
詳しくは、以下を参照(っていうか、以下のサイトに書いてあることをやってるだけだ)
JAXPのすべて 第1回
http://www-06.ibm.com/jp/developerworks/xml/050610/j_x-jaxp2.html
■ソース
仕様は、
・Access2003を使って、test.xmlとtest.xsdを作成し
・それを読み込んで、バリデーションチェックする
というもの。Java1.5を使ってます。
import java.io.*; import javax.xml.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; import javax.xml.validation.*; import org.w3c.dom.*; public class test { /* * メイン処理(呼び出し元) */ public static void main(String[] args) { try { //==============================// // 読み込む // //==============================// FileInputStream fi = new FileInputStream("test.xml"); // ドキュメントビルダーファクトリを生成 DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); dbfactory.setValidating(true); // ドキュメントビルダーを生成 DocumentBuilder builder = dbfactory.newDocumentBuilder(); // パースを実行してDocumentオブジェクトを取得 Document xtree = builder.parse(fi); //==============================// // 正しいかチェック // //==============================// // XMLスキーマセット=> validatorとってくる SchemaFactory constraintFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Source constraints = new StreamSource(new File("test.xsd")); Schema schema = constraintFactory.newSchema(constraints); Validator validator = schema.newValidator(); // チェック開始 validator.validate(new DOMSource(xtree)); fi.close(); System.out.println("Job End"); } catch (Exception e) { e.printStackTrace(); } } } |
(上記 < > ¥ は本当は半角です)
なんか、はじめの(1)に相当するところで変なメッセージがでる。意味不明。
ありえないタグをいれて(ただし構文的には解した具と終了タグを入れてちゃんとしておく)と、ちゃんと、エラーではじいてくれた。