如何通过验证器获取有关无效 DOM 元素的更多信息?
我正在使用 javax.xml.validation.Validator 类针对 XSD 架构验证内存中 DOM 对象。每当我填充 DOM 的信息中存在一些数据损坏时,我就会在验证期间抛出 SAXParseException
。
错误示例:
org.xml.SAXParseException: cvc-datatype-valid.1.2.1: '???"??[??????G?>???p~tn??~0?1]'不是“hexBinary”的有效值。
我希望有一种方法可以在内存 DOM 中找到此错误的位置并打印出有问题的元素及其父元素:
public void writeDocumentToFile(Document document) throws XMLWriteException {
try {
// Validate the document against the schema
Validator validator = getSchema(xmlSchema).newValidator();
validator.validate(new DOMSource(document));
// Serialisation logic here.
} catch(SAXException e) {
throw new XMLWriteException(e); // This is being thrown
} // Some other exceptions caught here.
}
private Schema getSchema(URL schema) throws SAXException {
SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// Some logic here to specify a ResourceResolver
return schemaFactory.newSchema(schema);
}
已经研究过 。这Validator#setErrorHandler(ErrorHandler handler)
方法,但 ErrorHandler
接口只让我暴露于 SAXParseException
,它只暴露行号和列号因为我使用的是内存 DOM,所以行号和列号都返回 -1,
我真的不想在添加字符串之前手动验证它们。 DOM(如果库为我提供)我正在寻找的函数。
我正在使用 JDK 6 update 26 和 JDK 6 update 7,具体取决于此代码的运行位置
:添加此代码后,
validator.setErrorHandler(new ErrorHandler() {
@Override
public void warning(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
@Override
public void error(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
private void printException(SAXParseException exception) {
System.out.println("exception.getPublicId() = " + exception.getPublicId());
System.out.println("exception.getSystemId() = " + exception.getSystemId());
System.out.println("exception.getColumnNumber() = " + exception.getColumnNumber());
System.out.println("exception.getLineNumber() = " + exception.getLineNumber());
}
});
我得到输出:
exception.getPublicId() = null
exception.getSystemId() = null
exception.getColumnNumber() = -1
exception.getLineNumber() = -1
I am validating an in-memory DOM object using the javax.xml.validation.Validator
class against an XSD schema. I am getting a SAXParseException
being thrown during the validation whenever there is some data corruption in the information I populate my DOM from.
An example error:
org.xml.SAXParseException: cvc-datatype-valid.1.2.1: '???"??[?????G?>???p~tn??~0?1]' is not a valid valud for 'hexBinary'.
What I am hoping is that there is a way to find the location of this error in my in-memory DOM and print out the offending element and its parent element. My current code is:
public void writeDocumentToFile(Document document) throws XMLWriteException {
try {
// Validate the document against the schema
Validator validator = getSchema(xmlSchema).newValidator();
validator.validate(new DOMSource(document));
// Serialisation logic here.
} catch(SAXException e) {
throw new XMLWriteException(e); // This is being thrown
} // Some other exceptions caught here.
}
private Schema getSchema(URL schema) throws SAXException {
SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// Some logic here to specify a ResourceResolver
return schemaFactory.newSchema(schema);
}
I have looked into the Validator#setErrorHandler(ErrorHandler handler)
method but the ErrorHandler
interface only gives me exposure to a SAXParseException
which only exposes the line number and column number of the error. Because I am using an in-memory DOM this returns -1 for both line and column number.
Is there a better way to do this? I don't really want to have to manually validate the Strings before I add them to the DOM if the libraries provide me the function I'm looking for.
I'm using JDK 6 update 26 and JDK 6 update 7 depending on where this code is running.
EDIT: With this code added -
validator.setErrorHandler(new ErrorHandler() {
@Override
public void warning(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
@Override
public void error(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
printException(exception);
throw exception;
}
private void printException(SAXParseException exception) {
System.out.println("exception.getPublicId() = " + exception.getPublicId());
System.out.println("exception.getSystemId() = " + exception.getSystemId());
System.out.println("exception.getColumnNumber() = " + exception.getColumnNumber());
System.out.println("exception.getLineNumber() = " + exception.getLineNumber());
}
});
I get the output:
exception.getPublicId() = null
exception.getSystemId() = null
exception.getColumnNumber() = -1
exception.getLineNumber() = -1
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用 Xerces(Sun JDK 默认值),您可以通过 http://apache.org/xml/properties/dom/current-element-node 属性:
示例:
如果需要从 DOM 获取行号/列号, <一href="https://stackoverflow.com/questions/4915422/get-line-number-from-xml-node-java">此答案解决了该问题。
If you are using Xerces (the Sun JDK default), you can get the element that failed validation through the http://apache.org/xml/properties/dom/current-element-node property:
Example:
If you need to get line/column numbers from the DOM, this answer has a solution to that problem.
SaxParseException 公开 SystemId 和 PublicId。这还没有给你足够的信息吗?
SaxParseException exposes the SystemId and PublicId. Does that not give you enough information?