2

Validator在使用 Java 的 XML (我相信它使用 Apache Xerces 实现)时,我遇到了一些看起来非常奇怪的行为。

我正在尝试针对 XSD 验证一些 XML 文档,并且我想记录任何导致文档无效的内容。我认为实现我自己的ErrorHandler可以让我做到这一点。我很快发现这会导致错误地验证 XML 文档(即无效的 XML 被识别为对我的 XSD 有效)。

我做了一些测试,发现简单地将Validator's设置ErrorHandler为任何东西都会导致这种行为,如下所示。

validator.validate(invalidXmlSource); // XML correctly identified as INVALID

validator.setErrorHandler(new DefaultHandler());
validator.validate(invalidXmlSource); // XML incorrectly identified as VALID

我会假设未指定Validator用途DefaultHandler时的用途,所以我不明白为什么行为会发生变化。

这里发生了什么?

编辑

public void validate(File dir, String xsdPath) {
    File schemaFile = new File(xsdPath);
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(schemaFile);
    Validator validator = schema.newValidator();
    //validator.setErrorHandler(new DefaultHandler()); <-- this line causes incorrect validation
    for (File xmlFile: dir.listFiles()) {
        try {
            validator.validate(new StreamSource(xmlFile));
            System.out.println("File '" + xmlFile.getName() + "' is valid.");
        } catch (SAXException e) {
            System.out.println("File '" + xmlFile.getName() + "' is NOT valid.");
            System.out.println("Reason: " + e.getLocalizedMessage());
        } catch (IOException e) {
            e.printStackTrace();
        }       
    }
}
4

1 回答 1

6

DefaultHandler不会为errorand做任何事情warning。但是,它会为fatalError. 在 和 的文档之间ValidatorDefaultHandler您会看到,无论好坏,您得到的正是您所要求的。:)

编辑:文档中要注意的主要事情可能Validator是默认(null)错误处理程序将引发异常error...

Edit2:这是一个可能的错误处理程序的概要,可以执行您想要的操作:

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;

public class LoggingErrorHandler implements ErrorHandler {

    private boolean isValid = true;

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

    @Override
    public void warning(SAXParseException exc) {
        // log info
        // valid or not?
    }

    @Override
    public void error(SAXParseException exc) {
        // log info
        this.isValid = false;
    }

    @Override
    public void fatalError(SAXParseException exc) throws SAXParseException {
        // log info
        this.isValid = false;
        throw exc;
    }
}

它可以像这样使用:

LoggingErrorHandler errorHandler = new LoggingErrorHandler();
validator.setErrorHandler(errorHandler);
validator.validate(invalidXmlSource);
if (!errorHandler.isValid()) {
    //...
}
于 2012-09-11T20:22:15.170 回答