JAXB:XML验证期间的严重性2事件(致命错误)而不是严重性1事件(错误)

时间:2015-07-13 16:58:01

标签: java jaxb jaxb2

在使用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上都有这种行为。

1 个答案:

答案 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”方法的错误)。

不好,我知道。但正如我所说,非常肮脏的解决方法