- - PR -
■XML schema検証:メモリについて
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2007-07-30 12:07
こんにちは。いつもお世話になっております。
xmlでの検証について質問です。 現在xmlファイルをDOMで読み込んでいるのですが、xmlファイルのサイズが大きくなることを想定し、SAX読み込みに変更しようとしています。 その際、現在おこなっているschema検証の方法について、疑問が出てきてしまいました。。 下記のソースが該当部分なのですが、DocumentBuilderFactoryはDOM系です。 そうしますと、ソース読み込み時にSAXを使用したところで検証時にDOMを使用してしまうとマズイと思われます… 〜 省略 〜 try{ String xsd = "(XSD_PATH)"; //DocumentBuilderFactoryのインスタンスを生成 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //妥当性検証に必要な設定 dbf.setNamespaceAware(true); dbf.setValidating(true); dbf.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", xsd); //DocumentBuilderのインスタンスを生成 DocumentBuilder db = dbf.newDocumentBuilder(); //エラーハンドラー設定 XmlCheckErrorHandler xceh = new XmlCheckErrorHandler(); db.setErrorHandler(xceh); db.parse("(---xmlFileName---)"); }catch(SAXException ex){ }catch(Exception ex){ } 〜 省略 〜 皆さん、メモリをできるだけ消費しないようにどのようなSchema検証を行なっていらっしゃいますか? どうかご教授のほど、よろしくお願いいたします。 |
|
投稿日時: 2007-07-31 13:40
XMLSchema はほとんどと言っていいほど理解していないので Relax NG ベースの話になりますがご了承ください。
RelaxNGCC というツールがあります。 このツールに Relax NG のスキーマファイルを処理させると、そのスキーマに沿った XML を読み込むパーザクラスを生成します。 このパーザクラスは指定したスキーマに基づくオートマトンになっており、スキーマに適合しない XML ファイルを読ませると受理せずに例外が発生します。つまり、正常に読めたならば検証済み、検証が失敗するようなものはそもそも読めないということです。 JDK のバージョンが書かれていませんが、JDK 5 以降であれば javax.xml.validation パッケージ下に検証用クラス群がまとめられ、読み込みと検証が分離されてすっきりしているようです。私自身がコードを書いて確認したわけではありませんが、スキーマ定義言語として XMLSchema も Relax NG もサポートしているとアナウンスされています。 このあたりを調査されるとよろしいかもしれません。 1.4 でも RelaxNGCC を使えば良いと思いますが、イベントに対するアクション部の書き方が UNIX の yacc や GNU bison、Java では JavaCC での方法を基にしています。これらをご存知ならばすぐに問題なく使えると思いますが、そうでない場合はやや難しいかもしれません。 |
|
投稿日時: 2007-07-31 18:19
Gio 様、アドバイス頂きありがとうございます。
”javax.xml.validation”は http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/javax/xml/validation/package-summary.html の使用例によるとDocument(org.w3c.dom.Document)を利用します。 恐らくDOM系のものだと思われるので、こちらは使用を避けたいのです。 スキーマはXMLSchemaで既に作成されているものがあるので、できればそれを使用したいと思っています。 (RelaxNGCCはRelaxNGで作成したスキーマファイルを使用するもの…ですよね。。) 説明不備があり、誠に申し訳ございませんでした。 一応現段階ではDOM系でないもの、スキーマはXMLSchemaで作成したもので探しています。 ですが、この方法も今後の参考にさせていただきたいと思います。 ご丁寧なアドバイスを頂き、誠にありがとうございました。 |
|
投稿日時: 2007-07-31 23:03
DocumentBuilderFactory,DocumentBuildeの代わりに、SAXParserFactory,SAXParserを使えばよいと思います。
最近SAXを使っていないので細かい部分は覚えていないのですが、APIを見る限り、DOMの場合とあまり違いがなさそうです。 [追記] SAXParserではなく、XMLReaderを使うみたいですね。 [ メッセージ編集済み 編集者: けむ 編集日時 2007-07-31 23:06 ] |
|
投稿日時: 2007-07-31 23:11
後で読み返して気付いたのですが、何だかピンぼけなことを書いてしまいました。
混乱された方がいらっしゃったらお詫び申し上げます。 XMLSchema ベースで簡単なサンプルを書いてみようかと考えていたところ、検索してみると IBM のサイトにしま太郎さんのご要望にかなり近いと思われるソースがありました。 お役に立てば幸いです。 ヒント:パーサにどこでスキーマを探せばよいかを教える http://www-06.ibm.com/jp/developerworks/xml/030822/j_x-tipvalschm.html (リスト 2 が対象 XML と XMLSchema 形式のスキーマを引数にとって SAX パージングをしながら検証するクラス、リスト 3 がエラーハンドラクラスです。 JAXP 1.2 と書いてあるので、JDK 1.4 であれば問題ないでしょう。) javax.xml.validation パッケージについてですが、確かに使用例中のコメントには DOM の記述があるものの、javax.xml.validation.Validator (もしくは ValidatorHandler)の派生クラスの validate() メソッドに javax.xml.transform.sax.SAXSource のインスタンスを渡すと SAX の検証ができるように読めました。 ご確認ください。 |
|
投稿日時: 2007-08-01 11:30
お教えいただいた”SAXParserFactory”を使用してスキーマ検証することができました。
けむ様、XMLReaderのInputSourceを使ってできそうです。 Gio様、URLをお教え頂きありがとうございます。細かい説明がされているサイトでしたので助かりました。 お二人とも、ご丁寧なアドバイスを頂きありがとうございました。 |
1