【问题标题】:Determine which XSD an XML instance failed against during validation确定 XML 实例在验证期间失败的 XSD
【发布时间】:2012-10-16 22:19:18
【问题描述】:

我正在针对多个 XSD 模式验证一个 xml 实例。如果验证失败,我想确定 xml 实例失败的架构。 SAXParseException 没有包含足够的信息来确定这一点。

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Source[] sources = getXsdSources();
Schema schema = factory.newSchema(sources);
Validator validator = schema.newValidator();

try {
  validator.validate(input);
} catch (SAXParseException e) {
  // Error handling.
}

【问题讨论】:

    标签: java validation xsd


    【解决方案1】:

    @Joe,以下链接可能会对您有所帮助。您可以在之前的 Stackoverflow 中找到相同的问题。 Validate an XML File Against Multiple Schema Definitions

    【讨论】:

    • 我看过那个帖子。 OP 遇到的问题是某些模式无法正确解析。我在加载模式时没有任何问题,我正在尝试做的是找出我的实例失败的模式。
    • 当然,除非我错过了帖子中的某些内容。您能否在回答中指出实际的解决方案是什么,而不是仅仅引用另一篇帖子而不另外发布相关解决方案。 (想想如果该链接失效会发生什么。)
    • @Joe:我是 Java 新手。我之前就是这样做的。我已将 StreamInstanceValidator jar 文件加载到我的类路径中,并使用以下命令在命令提示符中进行验证。 java org.apache.xmlbeans.impl.tool.StreamInstanceValidator -dl %2.xml %5.xsd > %2.txt
    • 我完全不知道你的评论是什么意思。此外,正如我之前在其他评论中提到的,如果您在其他帖子中找到相关解决方案,请将其添加到您的答案中,而不仅仅是发布链接。
    【解决方案2】:

    您需要单独验证每个架构,而不是将它们全部加载到“架构”中。那么它是一个简单的迭代“源”列表的简单问题,将“验证器”设置为每个,这样您就可以跟踪在失败时加载了哪些。

    这没有经过测试,但应该是正确的:

    SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
        Source[] sources = getXsdSources();
        foreach( Source s : sources){
        Schema schema = factory.newSchema(s);
        Validator validator = schema.newValidator();
        try {
          validator.validate(input);
        } catch (SAXParseException e) {
          // Error handling.
          System.out.println("failed on " + s.getSystemID)
        }
    }
    

    【讨论】:

    • 我已经尝试过这种方法,但我遇到的挑战是,如果我针对不是根类型的子模式进行验证,那么我会得到SAXParseException: cvc-elt.1: Cannot find the declaration of element 's:MyElement'。因此,如果 schemaA 导入 schemaB 并在内部元素上使用 schemaB,如果我专门针对 schemaB 进行验证,验证将失败并出现上述异常。
    【解决方案3】:

    Xerces J 提供对所有(或可能仅几乎所有?)后模式验证信息集 (PSVI) 的访问,其中包括有关验证元素或属性所依据的类型的信息,以及任何无效的性质。请参阅http://xerces.apache.org/xerces2-j/faq-xs.html#faq-8 了解更多信息。

    如果您使用的验证器是 Xerces J,则您需要的信息是可用的(可能在您正在处理的 SAXParseException 包装的异常中?);如果您使用的是另一个验证器,您可以进一步探索它的 API,也可以使用 Xerces J。

    【讨论】:

    • 我最终重构了我的验证过程,只传递了根命名空间的模式。虽然我仍然无法判断它是主模式还是导入模式,但我认为将它们指向根模式总比没有好。我查看了 Xerces,它可能有效,但没有尝试实现它。
    猜你喜欢
    • 2019-06-23
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    相关资源
    最近更新 更多