在使用JAXB对XSD文件进行XML验证期间,我似乎得到严重性为2的事件(致命错误),而不是严重性为1的事件(错误)。
要查看我的展示,我使用Unmarshal演示使用了博客条目JAXB and Marshal/Unmarshal Schema Validation at Blaise Doughan's Blog中发布的代码的精确副本。而不是在该博客上显示的三个严重性1事件,我得到严重性2事件。这是我的输出:
EVENT SEVERITY: 2 MESSAGE: cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLength '5' for type 'stringMaxSize5'. LINKED EXCEPTION: org.xml.sax.SAXParseException; systemId: file:/C:/.../workspace/JAXBTest/input.xml; lineNumber: 2; columnNumber: 25; cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLength '5' for type 'stringMaxSize5'. LOCATOR LINE NUMBER: 2 COLUMN NUMBER: 25 OFFSET: -1 OBJECT: null NODE: null URL: file:/C:/.../workspace/JAXBTest/input.xml EVENT SEVERITY: 2 MESSAGE: cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid. LINKED EXCEPTION: org.xml.sax.SAXParseException; systemId: file:/C:/.../workspace/JAXBTest/input.xml; lineNumber: 2; columnNumber: 25; cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid. LOCATOR LINE NUMBER: 2 COLUMN NUMBER: 25 OFFSET: -1 OBJECT: null NODE: null URL: file:/C:/.../workspace/JAXBTest/input.xml EVENT SEVERITY: 2 MESSAGE: cvc-complex-type.2.4.d: Invalid content was found starting with element 'phone-number'. No child element is expected at this point. LINKED EXCEPTION: org.xml.sax.SAXParseException; systemId: file:/C:/.../workspace/JAXBTest/input.xml; lineNumber: 5; columnNumber: 19; cvc-complex-type.2.4.d: Invalid content was found starting with element 'phone-number'. No child element is expected at this point. LOCATOR LINE NUMBER: 5 COLUMN NUMBER: 19 OFFSET: -1 OBJECT: null NODE: null URL: file:/C:/.../workspace/JAXBTest/input.xml
在我自己的项目中,我想收集XML文件的所有无效点。到目前为止,这并不起作用,因为我得到XML文件的大多数无效部分的严重性2事件,即使只有一个超出其指定范围的值。
如何获得简单XML验证错误的预期严重性1分类?是否有任何机制可以更改JAXB中XML验证事件的分类?
另一方面,即使存在致命错误,我也可以将我的异常处理程序配置为继续,但我不认为这是个好主意。
最初,我想使用JAXB的ValidationEventCollector,但它通常只收集第一个事件,因为它在发生致命错误(严重性为2)时停止,就我所见,几乎每个验证问题就是这种情况。
我正在使用Java 1.8.0,我在Windows系统和Mac上都有这种行为。
答案 0 :(得分:0)
我已经尝试了几天来找到一种方法来做到这一点,但无济于事。显然,JAXB 人员认为将致命错误与解组上下文中的错误区分开来是没有用的。所以他们决定将错误映射到致命错误:
validator.setErrorHandler(new FatalAdapter(getContext()));
还有问题中的 FatalAdapter
:
/**
* Maps an error to a fatal error.
*
* @author Kohsuke Kawaguchi
*/
public class FatalAdapter implements ErrorHandler {
[...]
public void error (SAXParseException exception) throws SAXException {
core.fatalError(exception);
}
[...]
}
现在信息丢失了。
我什至尝试在运行时使用反射(我知道,不好)来解决这个问题,但是该类在方法中被实例化为局部变量,因此我无法访问它。我认为这需要一个补丁。
我最终在解组(并读取输入两次)之前进行了抢占式验证。
编辑:我可能已经找到了方法。但这是一个非常非常肮脏的解决方法。如果您检查随验证事件收到的 SAXParseException 的堆栈跟踪,您会注意到:
org.xml.sax.SAXParseException; lineNumber: 9; columnNumber: 1; XML document structures must start and end within the same entity.
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
我使用异常的来源来确定严重性(来自“fatalError”方法的致命错误和来自“error”方法的错误)。
不好,我知道。但正如我所说,非常肮脏的解决方法。