gpt4 book ai didi

java - 如何通过 validator 获取有关无效 DOM 元素的更多信息?

转载 作者:数据小太阳 更新时间:2023-10-29 01:56:44 25 4
gpt4 key购买 nike

我正在使用 javax.xml.validation.Validator 类针对 XSD 模式验证内存中的 DOM 对象。每当我从中填充 DOM 的信息中存在一些数据损坏时,我就会在验证过程中抛出 SAXParseException

错误示例:

org.xml.SAXParseException: cvc-datatype-valid.1.2.1: '???"??[?????G?>???p~tn??~0?1]' is not a valid valud for '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 接口(interface)只让我接触到一个 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

最佳答案

如果您使用的是 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);
}

例子:

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
}

如果您需要从 DOM 中获取行号/列号,this answer有解决该问题的方法。

关于java - 如何通过 validator 获取有关无效 DOM 元素的更多信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8077437/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com