自作しているといつの間にか複数のバージョンが登場しだします。
なので読み込みの部分で、
どのバージョンなのか調べてから検証しなければなりません。
ルート要素の"version"属性にバージョン情報があるとして、
どうやれば実現できるのか考えてみます。
まず最初に言いたいのは、
XMLスキーマに統一する必要があるということです。
"Trang"というツールでDTD→XMLスキーマの変換ができるのでやっておきます。
何かエラーが出たときは…うん、ごめんなさい。
そしたら読み込み部分の処理ですね。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.net.URL; | |
import javax.xml.XMLConstants; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
import javax.xml.transform.dom.DOMSource; | |
import javax.xml.validation.Schema; | |
import javax.xml.validation.SchemaFactory; | |
import org.w3c.dom.Document; | |
public class XmlChecker { | |
public static void main(String[] args) { | |
try { | |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
// 名前空間をサポートするか | |
factory.setNamespaceAware(true); | |
// DTD検証を行うか | |
factory.setValidating(false); | |
// XMLのパース | |
Document document = factory.newDocumentBuilder().parse("(XMLのURI)"); | |
// バージョン情報の取得 | |
String version = document.getDocumentElement().getAttribute("version"); | |
if (version.equals("1.0")) { | |
Schema schema = SchemaFactory.newInstance( | |
XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( | |
new URL("XMLスキーマバージョン1のURL")); | |
schema.newValidator().validate(new DOMSource(document)); | |
// バージョン1の処理 | |
} else if (version.equals("2.0")) { | |
Schema schema = SchemaFactory.newInstance( | |
XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( | |
new URL("XMLスキーマバージョン2のURL")); | |
schema.newValidator().validate(new DOMSource(document)); | |
// バージョン2の処理 | |
} else { | |
// エラー | |
} | |
} catch (Exception e) { | |
// エラー | |
} | |
} | |
} |
では軽く解説を…
まずパース時のDTD検証は無効にしています。
検証はパース後にしたいですしね。
XMLスキーマに寄せた理由もここら辺です。
で、DOMでバージョン番号を取得します。
後は各バージョンのスキーマを使って検証を行うだけっと。
例ではif文ですが、Mapとか使ってさばくのが大人の醍醐味。
あ、Schemaオブジェクトはスレッドセーフだから作りっぱなしでOKです。
XMLファイルのスキーマ情報は無視している…はずです。
もし何か悪さをしたらDocumentBuilderにEntityResolverを設定して適当に受け流してください。
これでXMLの後方互換性はバッチリ!
(…例によって誰得情報だ。)
0 件のコメント:
コメントを投稿