XMLSchemaで妥当性検証(javax.xml.validation.Validator)では、 Validatorクラスを使って、XML文書にスキーマファイルの位置を記述しないで検証する方法を解説しました。 Validatorクラスによる検証は、検証のためだけにストリームからの読み込みを行うのに対し、 本ページでは、ストリームからの読み込みとパースの両方を同時に行うことができる、ValidatorHandlerクラスを使用します。
用意するものは以下の3つです。
以下簡単なサンプルを紹介します。
public class SAXValidation {
public static void main(String[] args) throws SAXException, IOException {
XMLReader reader;
ValidatorHandler hValidator;
SchemaFactory sFac;
Schema schema;
MyContentHandler myContentHandler;
sFac = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schema = sFac.newSchema(new File("./sample.xsd"));
hValidator = schema.newValidatorHandler();
myContentHandler = new MyContentHandler();
hValidator.setContentHandler(myContentHandler);
reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(hValidator);
reader.parse("./sample.xml");
System.out.println("number1 要素の中身 = " + myContentHandler.number1);
System.out.println("number2 要素の中身 = " + myContentHandler.number2);
}
// number1要素の中身とnumber2要素の中身を読み取るハンドラ
private static class MyContentHandler extends DefaultHandler {
private static final String EN_NUMBER1 = "number1";
private static final String EN_NUMBER2 = "number2";
private StringBuffer sb;
public String number1;
public String number2;
public void startElement(String uri, String localName, String qName,
Attributes attributes) {
if (EN_NUMBER1.equals(localName) || EN_NUMBER2.equals(localName)) {
sb = new StringBuffer();
}
}
public void characters(char[] ch, int start, int length) {
if (sb != null) {
sb.append(ch, start, length);
}
}
public void endElement(String uri, String localName, String qName) {
if (EN_NUMBER1.equals(localName)) {
number1 = sb.toString();
sb = null;
} else if (EN_NUMBER2.equals(localName)) {
number2 = sb.toString();
sb = null;
}
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number1>aiu</number1>
<number2>eo</number2>
</root>
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="root"> <xsd:complexType> <xsd:sequence> <xsd:element name="number1" type="xsd:string"/> <xsd:element name="number2" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>
ValidatorHandlerにContentHandlerを実装したインスタンスをセットすることで、ValidatorHandlerがフィルタとなり、 フィルタを通ってContentHandlerに処理が渡されます。 結果、妥当性を検証しながらパース処理を行うことができます。