java - 如何使用导入另一个模式文件的模式文件验证 XML?

标签 java xml xsd moxy xsd-validation

我想根据 this schema 验证 XML 文件(在 zipper 内);它导入另外两个 XSD 文件。

   <import namespace="http://www.w3.org/2000/09/xmldsig#" 
       schemaLocation="xmldsig-core-schema.xsd"/>
   <import namespace="http://www.w3.org/2001/04/xmlenc#" 
       schemaLocation="xenc-schema.xsd"/>

这 2 个文件也可以在这里找到:

验证时,我收到此错误:

Src-resolve: Cannot Resolve The Name 'xenc:EncryptedData' To A(n) 'element Declaration' Component.

我的验证/解码代码如下所示(使用 moxy 作为 JAXB 提供程序):

jaxbContext = JAXBContext.newInstance(type.getRequestType().getPackage().getName());
Unmarshaller um = jaxbContext.createUnmarshaller();

SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/xsd/" + type.getXsdName())));
um.setSchema(schema);

root = um.unmarshal(new StreamSource(new ByteArrayInputStream(xmlData)), type.getRequestType());

在您询问该类型的作用之前:我编写了可以从 http://www.forum-datenaustausch.ch/ 导入所有类型发票的代码.但是 4.3 及以上版本使用了两个额外的模式文件。如何验证 XML 文件?

最佳答案

查看 this post 的已接受答案.根据我在你的帖子中看到的一点点,以及我所记得的,你加载 XSD 的方式的问题与按照你的方式进行的事实有关,工厂没有得到基本的 uri ,因此它不能应用它的智能来解析对其他两个 XSD 的引用。我必须假设您的其他两个 XSD 也作为资源打包在同一 jar 中的同一目录中。

我不得不承认我对错误消息很感兴趣,这似乎暗示它加载的模式是有效的,所以它可能是一个 XML 问题;如果以上内容对您没有帮助,那么您也应该考虑发布有问题的 XML...

更新:根据我的评论,它正在按描述工作。请参阅下面的代码片段:

SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema compiledSchema = schemaFactory.newSchema(new SOTests().getClass()
    .getClassLoader().getResource("generalInvoiceRequest_430.xsd"));
Validator validator = compiledSchema.newValidator();
try {
    validator.validate(new StreamSource("D:\\...\\dentist_ersred_TG_430.xml"));
    System.out.println("Valid.");
}
catch (SAXException ex) {
    System.out.print("Not valid because..." + ex.getMessage());
}  

除了第一个 XSD 之外,您不需要加载更多的内容,而且您也不应该加载,因为所有导入都会提供对架构位置的提示。

enter image description here

XSD 文件全部在生成的 jar 中的同一目录中,而且它们必须是,因为用于导入的相对 URI 表示相同的父级。

enter image description here

程序输出包含从 here 下载的文件之一:

Valid.

引入无效内容后:

Not valid because...cvc-complex-type.2.4.a: Invalid content was found starting with element 'wrong'. One of '{"http://www.forum-datenaustausch.ch/invoice":processing}' is expected.

我对阅读本文的人的建议:

  • 使用 getResource() 获取 URL;正如我在上面所说的,StreamResource 没有基本 URI,因此无法取消引用根据您的 xsd:import schemaLocation 属性的相对引用。
  • 让架构/工厂在明确提供时为您加载。
  • 确保提供时,相对引用与您的 jar 文件中的文件夹结构相匹配。

关于java - 如何使用导入另一个模式文件的模式文件验证 XML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15619653/

相关文章:

java - MySQL服务器配置问题

java - Android 中循环随机图像

xml - 如何在 XML 中的元素之间创建引用

java - 出于 OSGI 目的将 jfxrt 移至 lib/ext

java - 整洁架构中具有单一依赖性的用例

java - 如何通过http获取xml文件?

xml - XPath/XSLT选择所有 sibling ,包括 self

xml - XML模式头和命名空间配置

java - 将 XSD 转换为原型(prototype)

java - 启动时清空 RecyclerView,然后通过 onclick 监听器在其上添加项目