跨项目指定 XSD schemaLocation 的正确或正确方法是啥?

Posted

技术标签:

【中文标题】跨项目指定 XSD schemaLocation 的正确或正确方法是啥?【英文标题】:What's the correct or proper way to specify XSD schemaLocation across projects?跨项目指定 XSD schemaLocation 的正确或正确方法是什么? 【发布时间】:2013-03-13 07:13:31 【问题描述】:

假设我有两个项目,A 和 B。Java 项目,以防万一。

项目 A 包含一堆代表核心类型和元素的 XSD 文件。它们都放在一个叫做“定义”的包中。这内置于project-a.jar

Project B 代表一个扩展项目,它可以定义自己的类型和元素。我创建了一个新模式并将其放在“definition.extension”包中。这内置于project-b.jar

现在,对于项目 B 中的 XSD,对于 include,我究竟应该将 schemaLocation 放在什么位置?

schemaLocation="../core-types.xsd" 不太好用(我知道,它需要一个 URI),但正确或标准的方法到底是什么?谷歌发现有更多的人问我这个问题,这些问题的明确标准方法是什么才是真正正确的处理方法。

不可能是我在运行时以编程方式调整了schemaLocation...或者我需要一个构建步骤/脚本来在编译过程中动态替换schemaLocation...对吗?

我不是在寻找诸如“将它们放在共享位置”之类的答案。我正在寻找更多类似于使用相对引用而不是硬编码引用的开发环境的东西。

仅供参考,我正在使用 IntelliJ IDEA,以防有特定于 IDE 的方法。

【问题讨论】:

EntityResolver 可能是运行时的技术解决方案。 URI 也可以引用嵌入在 jar 中的文件。见this post。 也许是 Class.getResource() 或 ClassLoader.getResource()?见this post 你试过类似 schemalocation="classpath:core-types.xsd" 吗? 【参考方案1】:

如果您只是希望 IntelliJ 停止以红色显示您的包含,您可以在您的包含中使用一些自定义 URI。然后转到项目设置 -> 架构和 DTD,您可以在其中将此 URI 映射到本地文件。

如果您需要在运行时进行架构验证,那就另当别论了。您可能需要使用 XML 目录。如果你使用 JAXB,你应该看看这个问题:jaxb - how to map xsd files to URL to find them

【讨论】:

【参考方案2】:

您应该使用XML Catalogs。此链接由 XML 专家 Norman Walsh 全面介绍了 XML 目录 - 以及如何在 Java 中使用它们。引用:

这些目录文件可用于将公共和系统标识符以及其他 URI 映射到本地文件(或只是其他 URI)。

上述标识符通常是您在架构imports 中使用的schemalocations 或namespaces。

在使用此类目录时,为了避免混淆和某些bug in XJC,我强烈建议您从XML 模式中的模式导入中删除所有schemaLocations,并且只保留namespace(如果您有选择当然)。例如:

<import namespace="http://www.w3.org/1999/xlink" />

然后指定每个命名空间到目录中实际架构位置的映射。例如,使用 OASIS XML 目录格式:

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
    <uri name="http://www.w3.org/1999/xlink" uri="w3c/1999/xlink.xsd" />
</catalog>

在编译时,如果您要从模式生成带有 JAXB 注释的类,我建议您使用 Episodes 来实现单独的模式编译,也就是 modular schema compilation。例如,maven-jaxb2-plugin 支持这一点,它还对catalogs 提供高级支持。

对于运行时,根据您的 XML 用例,您应该尝试使用原生支持 XML 目录的库,例如大多数 Java Web 服务框架(JAX-WS RI/Metro、Apache CXF...),如果您例如,正在开发 Web 服务。如果您不能或想要更好地控制 XML 目录(例如,能够从类路径加载模式),我邀请您查看前面提到的 XML Entity and URI Resolvers 页面,尤其是部分 Using Catalogs with流行的应用程序为您的应用程序添加目录支持。基本上,您可以使用org.apache.xml.resolver.tools.CatalogResolver 和可选的(为了更好地控制)org.apache.xml.resolver.CatalogManager 类。自定义CatalogResolver/CatalogManager的具体例子可以看Apache的代码源commons-configuration、AuthzForce、CXF等。

【讨论】:

以上是关于跨项目指定 XSD schemaLocation 的正确或正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 schemaLocation 或 noNamespaceSchemaLocation 将 XML 链接到 XSD?

在 C# 中针对引用的 XSD 验证 XML

反序列化然后序列化时保留 Xml Xsd schemaLocation

关于Spring

面对问题包括使用spring boot在wsdl中的schemalocation

Spring配置文件xsi:schemaLocation无法解析导致启动失败的解决方案