我正在将XML文件解组为JAXB生成的Java对象。我希望unmarshaller根据进程中的模式验证文件。模式的.xsd
文件位于依赖项.jar
文件中。我这样设置架构:
ClassLoader classLoader = getClass().getClassLoader();
InputStream schemaStream = classLoader.getResourceAsStream(schemaFilePath);
StreamSource schemaSource = new StreamSource(schemaStream);
Schema schema = factory.newSchema(schemaSource);
unmarshaller.setSchema(schema);
除了一个问题之外,这主要是有效的。该模式将一些复杂类型分解为其他.xsd
文件。 unmarshaller似乎无法找到已分解的.xsd
文件,因为当我尝试设置架构时,我得到了SAXException
:
Cannot resolve the name 'tns:FactoredOutType' to a(n) 'type definition' component.
注意:从eclipse运行时,当它引用.xsd
文件夹而不是target
文件中的.jar
文件时,此方法正常。
任何人都有任何想法如何让依赖的.xsd
文件中的模式使用的因子.jar
文件?
编辑:
如果它是有用的信息,则顶级.xsd
位于model
文件夹中,其引用的类型位于model/common
,因此我引用了顶级.xsd
1}} as:
"model/TopLevel.xsd"
...并且在其中,它将因子分解.xsd
引用为:
"common/FactoredOut.xsd"
答案 0 :(得分:0)
我们有一些XSD导入/包含其他XSD。我们通过将它们全部传递给SchemaFactory
来实现这一点,而不是依赖于导入工作并在类路径中找到它。这是代码的样子:
try (InputStream xsdStream0 = ClaimLoadService.class.getResourceAsStream("/a.xsd");
InputStream xsdStream1 = ClaimLoadService.class.getResourceAsStream("/b.xsd");
InputStream xsdStream2 = ClaimLoadService.class.getResourceAsStream("/c.xsd");
InputStream xsdStream3 = ClaimLoadService.class.getResourceAsStream("/d.xsd");
InputStream xsdStream4 = ClaimLoadService.class.getResourceAsStream("/e.xsd");) {
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schema = sf.newSchema(new Source[] { new StreamSource(xsdStream0), new StreamSource(xsdStream1),
new StreamSource(xsdStream2), new StreamSource(xsdStream3), new StreamSource(xsdStream4) });
...
} catch (SAXException | IOException | JAXBException e) {
logger.log(Level.INFO, e.getMessage(), e);
}
为了使JAXB完全满意,我们有时必须做的另一件事是确保导入模式实际引用导入的类型。我不记得确切的错误,表明我们需要做出解决方法,但也许这就是你要打的。它很俗气,但我们这样做是一种解决方法:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://blah" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:name="http://blahblah" targetNamespace="http://blah"
elementFormDefault="qualified">
<xs:import namespace="http://blahblah" />
...
<xs:element name="ReferencesToMakeTheseElementsVisibleToThisJaxbContext">
<xs:complexType>
<xs:sequence>
<xs:element name="Business" type="name:type" minOccurs="0" />
...
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
基本上,我们创建一个complexType只是为了明确引用一些导入的类型。我们只需要在没有直接引用类型的情况下执行此操作。
答案 1 :(得分:0)
通常,与XML相关的API有一种方法可以让程序员指定辅助文件的位置,称为资源解析。对于Schema,我认为您必须实现LSResourceResolver
并在调用SchemaFactory.setResourceResolver
之前将其传递给newSchema
。
答案 2 :(得分:0)
我最后通过将我的newSchema
调用从StreamSource
传递到传递URL
来修复此问题,URL schemaURL = objectType.getClassLoader().getResource(schemaPath);
if (schemaURL != null) {
Schema schema = factory.newSchema(schemaURL);
unmarshaller.setSchema(schema);
}
保留了基本URI,因此仍然可以找到包含的类型(正如@PetruGardea在评论中提到的那样)。结果代码如下所示:
#latest {
overflow-x: scroll;
overflow-y: hidden;
height: 80px;
white-space:nowrap
}
article{
box-shadow: 1px 1px 10px #999;
margin: 2px;
max-height: 150px;
cursor: pointer;
display:inline-block;
*display:inline;/* For IE7*/
*zoom:1;/* For IE7*/
vertical-align:top;
谢谢大家的帮助!