10

XML を XSD に対して検証する最善の方法を探した結果、java.xml.validator に出会いました。

API のサンプル コードを使用して、独自の ErrorHandler を追加することから始めました。

// parse an XML document into a DOM tree
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = parser.parse(new File("instance.xml"));

// create a SchemaFactory capable of understanding WXS schemas
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

// load a WXS schema, represented by a Schema instance
Source schemaFile = new StreamSource(new File("mySchema.xsd"));
Schema schema = factory.newSchema(schemaFile);

// create a Validator instance, which can be used to validate an instance document
Validator validator = schema.newValidator();

// Add a custom ErrorHandler
validator.setErrorHandler(new XsdValidationErrorHandler());

// validate the DOM tree
try {
    validator.validate(new DOMSource(document));
} catch (SAXException e) {
    // instance document is invalid!
}

...

private class XsdValidationErrorHandler implements ErrorHandler {
    @Override
    public void warning(SAXParseException exception) throws SAXException {
        throw new SAXException(exception.getMessage());
    }

    @Override
    public void error(SAXParseException exception) throws SAXException {
        throw new SAXException(exception.getMessage());
    }

    @Override
    public void fatalError(SAXParseException exception) throws SAXException {
        throw new SAXException(exception.getMessage());
    }
}

これは問題なく動作しますが、XsdValidationErrorHandler に渡されたメッセージには、問題のある XML がドキュメント内の正確な場所を示すものはありません。

"org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'X'. One of '{Y}' is expected."

すべてのコードを書き直さなくても、ErrorHandler に送信される独自のエラー メッセージを定義できるように、Validator の別のセクションをオーバーライドまたはプラグインする方法はありますか?

別のライブラリを使用する必要がありますか?

4

5 に答える 5

9

SaxExceptionの子孫であるSaxParseExceptionをキャッチしてみてください。それらの1つを取得すると、getLineNumber()、getColumnNumber()などのメソッドがあります。

于 2012-09-04T17:21:23.963 に答える
3

エラーの座標を取得するexception.getLineNumber()ことができます。これは同様の質問です。exception.getColumnNumber()

于 2012-09-05T12:50:51.233 に答える
3

解析時に検証します。これにより、位置情報が利用可能になり、ErrorHandler がそれを報告します。

を作成するSchema前に を作成しDocumentBuilderFactory、次のように適用します。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
dbf.setSchema(schema);

注: このsetValidating()メソッドは、DTD 検証を使用するかどうかを DBF に通知します。スキーマを設定すると、スキーマ検証を使用するように指示されます。

于 2012-09-04T17:15:59.890 に答える
1

SAXParseExceptionを見ましたか?行番号などの情報をお探しですか?@parcifelが述べたように、解析するときに検証する必要があります(より効率的でより良いエラー情報)。これを行うには、DocumentBuilderFactoryでスキーマを指定します

于 2012-09-04T17:14:39.520 に答える