[英]JAXB How to validate xml against more schemas
我正在使用以下代码:
Unmarshaller unmarshaller = inputXmlContext.createUnmarshaller();
SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
URL urlSchema = ProbeOutputTranslator.class.getResource("/a.xsd");
Schema schema = sf.newSchema(new File(urlSchema.toURI()));
针对a.xsd
验证xml。 问题是a.xsd
定义了一个抽象元素及其包含元素:
<xs:complexType name="abstract_operation" abstract="true"/>
<xs:element name="operation" type="ac:abstract_operation"/>
<xs:complexType name="so_operations">
<xs:sequence>
<xs:element ref="ac:operation" minOccurs = "0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
具体类型在b.xsd
中定义。 在xml文件中,默认名称空间是a.xsd
, b.xsd
的名称空间绑定到ops
前缀,如下所示:
<so_operations>
<ops:a_concrete_operation>
....
</ops:a_concrete_operation>
</so_operations>
当使用上述代码时,此设置当然会导致验证错误。 如何在验证时也考虑到b.xsd
模式?
模式仅位于程序的资源中(因此,模式位置不能在xml文件中定义)。
您可以通过编程将多个架构组合为一个架构,然后针对组合的架构进行验证。
SchemaFactory.newSchema()具有一个变体,该变体采用一组源文档,并将它们组合为一个Schema实例。 但是,已记录此方法的行为,就像为每个源文档创建一个具有导入指令的新架构文档一样。 结果,您无法将源文件与相同的目标名称空间合并,并且必须对源文档进行排序,以便在另一个名称空间请求时可以使用一个名称空间中的定义(我在文档中没有找到任何证明这一点的理由) 。
如果您可以通过URL或文件系统访问架构文档,则最佳解决方案是创建一个顶级架构文档,并使用显式import和include指令引用您的定义。
以下代码可能有助于入门:
URL xsdUrlA = this.getClass().getResource("a.xsd");
URL xsdUrlB = this.getClass().getResource("b.xsd");
SchemaFactory schemaFactory = schemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
//---
String W3C_XSD_TOP_ELEMENT =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\">\n"
+ "<xs:include schemaLocation=\"" +xsdUrlB.getPath() +"\"/>\n"
+ "<xs:include schemaLocation=\"" +xsdUrlA.getPath() +"\"/>\n"
+"</xs:schema>";
Schema schema = schemaFactory.newSchema(new StreamSource(new StringReader(W3C_XSD_TOP_ELEMENT), "xsdTop"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.