Tyl*_*eat 2 java xml xsd sax xerces
在使用Java的XML Validator(我相信使用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
Run Code Online (Sandbox Code Playgroud)
我会假设当没有指定一个时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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
DefaultHandler对于将什么也不做error和warning.但是,它会抛出异常fatalError.该文档的之间的Validator和DefaultHandler,你会看到,是好还是坏,你得到你问什么了.:)
编辑:可能在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;
}
}
Run Code Online (Sandbox Code Playgroud)
它可以像这样使用:
LoggingErrorHandler errorHandler = new LoggingErrorHandler();
validator.setErrorHandler(errorHandler);
validator.validate(invalidXmlSource);
if (!errorHandler.isValid()) {
//...
}
Run Code Online (Sandbox Code Playgroud)