使用 javax.xml.validation.Validator 针对 XSD 进行 XML 验证



xsd 包含如下声明:

<xsd:attribute name="IDENTIFIER" use="required" type="xsd:ID" />

xml 中有问题的行如下所示:

<HEADER IDENTIFIER="invalidId 01">

<HEADER IDENTIFIER="validId01">

类型 xsd:ID 另请参阅 http://books.xmlschemata.org/relaxng/relax-CHP-19.html

不允许定义、冒号、空格或以数字开头。如果在 eclipse ide 中打开生成的文件,并根据已声明的 xsd 进行验证,则会发现错误并发出正确的信号。但是,在 JUnit 测试期间,将加载相同的 xsd,并针对它验证生成的文件。此验证查找任何类型的格式错误的 xml,但找不到无效的属性 IDENTIFIER。

验证代码如下所示:

static boolean validate(Source source) {
    boolean success = false;
    try {
        Validator validator = mySchema.newValidator();
        success = validate(validator, source);
    } catch (SAXException e) {
        logger.info(MSG_BASE + "SAXException: " + e.getMessage());
    } catch (IOException e) {
        logger.info(MSG_BASE + "IOException: " + e.getMessage());
    }
    return success;
}

private static boolean validate(Validator validator, Source source) 
                                                    throws SAXException, IOException {
    ErrorHandler erH = new DefaultHandler2();
    validator.setErrorHandler(erH);
    validator.validate(source);
    return true;
}

有谁知道可能缺少什么来告诉验证者考虑对属性的限制?

我没有使用 DefaultHandler2,而是将自己的 ValidationErrorHandler 设置为:

public class ValidationErrorHandler extends DefaultHandler {

包括:

 @Override
public void error (SAXParseException e) throws SAXException {
throw new SAXParseException(e.getMessage(), buildLocator(e), e);

}

private Locator buildLocator(SAXParseException e) {
    Locator2Impl loc = new Locator2Impl();
    loc.setLineNumber(e.getLineNumber());
    loc.setColumnNumber(e.getColumnNumber());
    loc.setSystemId(e.getSystemId());
    loc.setPublicId(e.getPublicId());
    return loc;
}

警告和致命错误方法也是如此!目前我有我需要的一切!

您是正确的,xsd:ID s 可能不包含空格。

至于为什么您没有从 Java 验证代码收到错误,请注意,DefaultHandler2()会忽略所有解析事件。 特别是,关于error()方法:

默认实现不执行任何操作。应用程序编写者可以 在子类中重写此方法以对每个 错误,例如在日志文件中插入消息或将其打印到 控制台。

一般来说,事实上,org.xml.sax.ErrorHandler 的接口是这样记录的:

警告:如果应用程序未注册错误处理程序,则 XML 解析错误将不会报告,但 SAXParseExceptions 将 因致命错误而被抛出。为了检测有效性错误,一个 使用 error() 调用执行某些操作的错误处理程序必须是 注册。

Xerces2-J 中包含的 SAX 示例的源代码提供了这方面的良好示例。 特别是,Counter类显示了如何扩展DefaultHandler

最新更新