2017-10-12 181 views
0

我想编组和解组xsd。我有一个罐子说A.jar包含一个xsd文件说1.xsd。我试图通过使用JAXB来验证它,但它失败了。 1.xsd正在导入另外3个存在于不同jar(B. jar)中的模式。我怎样才能验证它,同时验证它1.xsd可以读取属于不同jar(B.jar)的导入文件。如何在验证时从不同位置(Jar)读取XSD架构

+0

“我试图通过使用JAXB验证它,但它失败” - 它以哪种方式失败,您能提供任何相关的代码片段或错误消息吗? – gareththegeek

回答

0

假设这两个jar都可以在类路径中使用,模式文件是否分布在不同的jar中并不重要。如果一个模式导入或包含另一个模式,重要的是该路径可以被解决。

假设您有一个包my.project.schemas,它存在于A.jarB.jar中。在A.jar该软件包中包含1.xsd,该文件在B.jar的相同包中导入2.xsd。如果1.xsd进口元素看起来像这样...

<xs:import namespace="https://www.example.com" schemaLocation="2.xsd" /> 

那么它应该工作。解析器负责定位其他模式,并且由于给定schemaLocation是相对的,因此解析器会查找它,因为它将不同jar文件中的相同包视为相同的位置。

如果有不同的软件包,事情会变得更加复杂。在这种情况下,您需要使用相对路径,可能需要在包层次结构中上下移动以引用正确的文件(例如:如果包additional是包my.project.schemas的成员,则为additional/2.xsd)。另一种选择是use a custom resolver。这使您可以拦截对外部资源的调用并以编程方式解决它们。

最后,请注意SchemaFactory用于创建Schema对象has a method that accepts an array of sources。如果您为每个模式文件创建一个Source并将其全部提供给工厂以创建一个Schema对象,则可以避免位置问题。实际上,您可以省略schemaLocation属性,因为可以在所有提供的模式中找到必要的引用。

在过去,我已经使用JAXB验证marshallers/unmarshallers,它们必须跨不同的包使用模式导入对方,这也可以跨越不同的jar。最后的解决方案是为工厂方法提供每架构Source,这是我首选的方法。