如何在SAXParseException的情况下获取XML元素信息

时间:2016-02-05 10:18:10

标签: java xml sax saxparser xerces

在标准java环境中针对xsd架构验证xml源时,我找不到获取有关验证失败的元素的信息的方法(在许多特定情况下)。

捕获SAXParseException时,元素的信息消失了。但是,在调试xerces.XmlSchemaValidator时,我可以看到原因是未定义的特定错误消息,以提供有关该元素的信息。

例如(在我的java演示中也是这种情况)“cvc-mininclusive-valid”错误以这种方式定义: cvc-minInclusive-valid:对于类型为“{2}”的minInclusive''{1}',值''{0}''不是facet-valid。 https://wiki.xmldation.com/Support/Validator/cvc-mininclusive-valid

我更希望的是,会产生这样的信息: cvc-type.3.1.3:元素“{0}”的值“{1}”无效。 https://wiki.xmldation.com/Support/Validator/cvc-type-3-1-3

调试xerces.XMLSchemaValidator时,我可以看到有两个连续的reportSchemaError(...)调用 - 第二个只发生,如果第一个确实返回而没有抛出异常。

有没有办法配置验证器使用第二种报告方式OR来丰富SAXParseException和元素信息?

请参阅下面的复制和粘贴以及可运行示例代码以获取进一步说明:

String xsd =
            "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
                    "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" version=\"1.0\">" +
                    "<xs:element name=\"demo\">" +
                    "<xs:complexType>" +
                    "<xs:sequence>" +

                    // given are two elements that cannot be < 1
                    "<xs:element name=\"foo\" type=\"xs:positiveInteger\" minOccurs=\"0\" maxOccurs=\"unbounded\" />" +
                    "<xs:element name=\"bar\" type=\"xs:positiveInteger\" minOccurs=\"0\" maxOccurs=\"unbounded\" />" +

                    "</xs:sequence>" +
                    "</xs:complexType>" +
                    "</xs:element>" +
                    "</xs:schema>";

    String xml =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                    "<demo>" +

                    "<foo>1</foo>" +
                    // invalid!
                    "<foo>0</foo>" +
                    "<bar>2</bar>" +

                    "</demo>";

    Validator validator = SchemaFactory
            .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
            .newSchema(new StreamSource(new StringReader(xsd)))
            .newValidator();


    try {
        validator.validate(new StreamSource(new StringReader(xml)));
    } catch (SAXParseException e) {

        // unfortunately no element or line/column info:
        System.err.println(e.getMessage());

        // better, but still no element info:
        System.err.println(String.format("Line %s -  Column %s - %s",
                e.getLineNumber(),
                e.getColumnNumber(),
                e.getMessage()));
    }

3 个答案:

答案 0 :(得分:2)

没有详细记录,但如果您有最新版本的Xerces-J(请参阅SVN Rev 380997),则可以验证new并查询DOMSource Validator 1}}检索验证器报告错误时正在处理的当前ErrorHandler节点。

例如,您可以编写Element之类的内容:

ErrorHandler

然后使用此public class ValidatorErrorHandler implements ErrorHandler { private Validator validator; public ValidatorErrorHandler(Validator v) { validator = v; } ... public void error(SAXParseException spe) throws SAXException { Node node = null; try { node = (Node) validator.getProperty( "http://apache.org/xml/properties/dom/current-element-node"); } catch (SAXException se) {} ... } 调用Validator,如:

ErrorHandler

获取发生错误的元素。

答案 1 :(得分:1)

尝试使用错误处理程序:

    public class LoggingErrorHandler implements ErrorHandler {

    private boolean isValid = true;

    public boolean isValid() {
        return this.isValid;
    }

    @Override
    public void warning(SAXParseException exc) {
        System.err.println(exc);
    }

    @Override
    public void error(SAXParseException exc) {
        System.err.println(exc);
        this.isValid = false;
    }

    @Override
    public void fatalError(SAXParseException exc) throws SAXParseException {
        System.err.println(exc);
        this.isValid = false;
        throw exc;
    }
}

并在验证器中使用它:

        Validator validator = SchemaFactory
                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
                .newSchema(new StreamSource(new StringReader(xsd)))
                .newValidator();
        LoggingErrorHandler errorHandler = new LoggingErrorHandler();
        validator.setErrorHandler(errorHandler);
        validator.validate(new StreamSource(new StringReader(xml)));
        return errorHandler.isValid();

答案 2 :(得分:-1)

我知道这很老了,但是Michael Glavassevich的回答却很迷人。我尚无法发表评论或发表评论,但这本书提供了他真正的深刻知识。