[英]How to get more specific errors when validating XML against an XSD using java.xml.validator
在搜索了针对XSD验证XML的最佳方法之后,我遇到了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."
有没有办法让我覆盖或插入Validator的另一部分,这样我就可以定义自己发送给ErrorHandler的错误消息,而不必重写所有代码?
我应该使用不同的图书馆吗?
尝试捕获SaxParseException,它是SaxException的后代。 如果你得到其中一个,它有方法getLineNumber(),getColumnNumber()等。
在解析时验证。 这将使位置信息可用,ErrorHandler将报告它。
只需在创建DocumentBuilderFactory
之前创建Schema
,然后像这样应用它:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
dbf.setSchema(schema);
注意: setValidating()
方法告诉DBF是否使用DTD验证。 设置架构告诉它使用架构验证。
您可以执行exception.getLineNumber()
和exception.getColumnNumber()
来获取错误的坐标。 这是一个类似的问题。
你看过SAXParseException了吗? 我假设您正在寻找行号等信息? 正如@parcifel所提到的,您应该在解析时进行验证(更高效和更好的错误信息)。 您可以通过在DocumentBuilderFactory上指定架构来完成此操作。
public class KitXsdErrorHandler implements ErrorHandler {
@Override
public void warning(SAXParseException exception) throws SAXException {
handleMessage("Warning", exception);
}
@Override
public void error(SAXParseException exception) throws SAXException {
handleMessage("Error", exception);
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
handleMessage("Fatal", exception);
}
private String handleMessage(String level, SAXParseException exception) throws SAXException {
int lineNumber = exception.getLineNumber();
int columnNumber = exception.getColumnNumber();
String message = exception.getMessage();
throw new SAXException("[" + level + "] Sətr nömrə: " + lineNumber + " Sütun nömrə: " + columnNumber + " message: " + message);
}
}
此信息也很有用
如何使用SAX XML Schema Validator的验证消息进行内部化?
http://vijiprakash.blogspot.com/2008/05/custom-error-message-in-xml-xsd.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.