DTD定義されたXMLを解析する
先日のXML文書に合わせてDTDを作成し、そのDTD定義を追加したXMLを解析するサンプルを書いてみる。
まず、DTD定義は次のようになる。
<!ELEMENT sample (elementA|elementB)*> <!ELEMENT elementA (name) > <!ELEMENT name (#PCDATA) > <!ELEMENT elementB (someTag)> <!ATTLIST elementB someAttr CDATA #REQUIRED> <!ELEMENT someTag EMPTY> <!ATTLIST someTag value CDATA #REQUIRED>
それぞれの行は、次のような意味を持つ。
- sample要素は、elementA要素、またはelementB要素を複数個持つ
- elementA要素は、子要素としてname要素を持つ
- name要素は子要素を持たない文字列
- elementB要素は、子要素としてsomeTag要素を持つ
- elementB要素は、属性としてsomeAttr属性を持ち、このsomeAttr属性は必須(#REQUIRED)
- someTag要素は子要素を持たない空要素である
- someTag要素は、属性としてvalue属性が必須
そして、XMLは次のようになる。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sample SYSTEM "sample.dtd"> <sample> <elementA> <name>ElementA_Name</name> </elementA> <elementB someAttr="B"> <someTag value="someValue"/> </elementB> </sample>
Javaの実装は次のようになる。なお、JDKは1.4.x系のものを想定しており、Xercesは1.4.3を利用している。
import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.ErrorHandler; import org.apache.xerces.parsers.DOMParser; import java.io.IOException; public class MySimpleParseWithValidation { public static void main(String[]args){ try { DOMParser parser = new DOMParser(); parser.setFeature("http://xml.org/sax/features/validation", true); parser.parse(args[0]); Document doc = parser.getDocument(); System.out.println(args[0] + " is a valid xml."); } catch( SAXException e ){ System.err.println("Parser error found: " + e.getMessage()); System.exit(1); } catch( IOException e ){ System.err.println("IO error found: " + e.getMessage()); System.exit(1); } } }
DTDの検証を指示しているのは、
parser.setFeature("http://xml.org/sax/features/validation", true);
という行。このsetFeatureメソッドは2つの引数が必要。
一つ目の文字列引数は、パーサに対してどのオプションを設定するか知らせるもの。
"http://xml.org/sax/features/validation"の場合は、妥当性チェックの実施可否を指定する。
第二引数がtrueなので、この例だと妥当性チェックが実施される。
falseの場合は、妥当性チェックは実施されず、整形式かどうかだけのチェックが行われる。
また、第一引数で定義できる文字列値は決まっており、存在しないものを指定した場合は実行時にSAXExceptionが投げられる。