当XSD驻留在JAR中时,如何使用包含另一个XSD和JAXB的XSD?

时间:2015-10-02 10:51:05

标签: java xml jar xsd jaxb

我正在读取通过XSD文件验证到XJC生成的类的XML文件。当我在普通文件系统中引用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(),但这没有帮助。

1 个答案:

答案 0 :(得分:2)

最简单的方法是使用URL,例如(未经测试):

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

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

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

sf.setResourceResolver(myResourceResolver);

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