如何在 XSD 驻留在 JAR 中时将包含另一个 XSD 的 XSD 与 JAXB 一起使用?

How to use XSD that includes another XSD with JAXB while XSDs reside in JAR?

我正在将通过 XSD 文件验证的 XML 文件读取到 XJC 生成的 类 中。当我在普通文件系统中引用 XSD 时,一切正常。现在我想将 XSD 捆绑到我的 JAR 中。只要 XSD 与以下代码独立,这也可以正常工作:

//Use the schema factory to get the schema
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

//Get XSD from JAR
InputStream schemaStream = getClass().getResourceAsStream("/schema/myschema.xsd");
Schema schema = sf.newSchema(new StreamSource(schemaStream));

//parse the XML file and fill the data model
Class<T> c = getXmlDataModelClass();
JAXBContext jaxbContext = JAXBContext.newInstance(c);

m_JaxbUnmarshaller = jaxbContext.createUnmarshaller();

//set the schema to be considered
m_JaxbUnmarshaller.setSchema(schema);

return (T)m_JaxbUnmarshaller.unmarshal(file);

现在的问题是:如果 myschema.xsd 包含另一个 XSD:

<xs:include schemaLocation="BaseTypes.xsd"/>

未找到包含的 XSD 中的类型。

我还尝试将两个 StreamSource 和两个 XSD 的数组传递给 sf.newSchema(),但这没有帮助。

最简单的是使用URLs,类似(未测试):

URL schemaURL = getClass().getResource("/schema/myschema.xsd");
Schema schema = sf.newSchema(schemaURL);

您将得到一个 jar:... URL 并将其提供给架构工厂。只要包含的模式驻留在同一个 JAR 中,就应该可以毫无问题地解决它们。

对于更高级的用法,您可以实例化并向架构工厂提供资源解析器:

sf.setResourceResolver(myResourceResolver);

资源解析器将架构解析为资源。例如,您可以使用 XMLCatalogResolver 之类的东西来使用目录文件重写模式 URLs。这将允许您将绝对 URLs 重写为本地资源。