Bri*_*128 5 java xml xml-validation
我正在使用javax.xml.validation.Validator针对XSD架构的类来验证内存中的DOM对象.SAXParseException每当在我填充DOM的信息中存在一些数据损坏时,我就会在验证期间抛出一个被抛出.
一个示例错误:
org.xml.SAXParseException:cvc-datatype-valid.1.2.1:'???? ?? [????? G?> p~tn ?? ~0?1]'无效'hexBinary'的价值.
我希望有一种方法可以在我的内存中找到这个错误的位置并打印出有问题的元素及其父元素.我目前的代码是:
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);
}
Run Code Online (Sandbox Code Playgroud)
我已经查看了该Validator#setErrorHandler(ErrorHandler handler)方法,但ErrorHandler界面只让我暴露于SAXParseException只暴露错误的行号和列号的a.因为我使用的是内存中的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());
}
});
Run Code Online (Sandbox Code Playgroud)
我得到输出:
exception.getPublicId() = null
exception.getSystemId() = null
exception.getColumnNumber() = -1
exception.getLineNumber() = -1
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Xerces(默认为Sun JDK),则可以通过http://apache.org/xml/properties/dom/current-element-node属性获取验证失败的元素:
...
catch (SAXParseException e)
{
Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");
System.out.println("Validation error: " + e.getMessage());
System.out.println("Element: " + curElement);
}
Run Code Online (Sandbox Code Playgroud)
例:
String xml = "<root xmlns=\"http://www.myschema.org\">\n" +
"<text>This is text</text>\n" +
"<number>32</number>\n" +
"<number>abc</number>\n" +
"</root>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
Schema schema = getSchema(getClass().getResource("myschema.xsd"));
Validator validator = schema.newValidator();
try
{
validator.validate(new DOMSource(doc));
}
catch (SAXParseException e)
{
Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");
System.out.println("Validation error: " + e.getMessage());
System.out.println(curElement.getLocalName() + ": " + curElement.getTextContent());
//Use curElement.getParentNode() or whatever you need here
}
Run Code Online (Sandbox Code Playgroud)
如果您需要从DOM获取行/列号,则此答案可以解决该问题.
| 归档时间: |
|
| 查看次数: |
2991 次 |
| 最近记录: |