在标准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()));
}
答案 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的回答却很迷人。我尚无法发表评论或发表评论,但这本书提供了他真正的深刻知识。