根据多个架构定义验证 XML 文件

2022-09-01 05:27:45

我正在尝试根据许多不同的架构验证XML文件(为人为的示例表示歉意):

  • a.xsd
  • b.xsd
  • c.xsd

c.xsd 特别导入 b.xsd 和 b.xsd 导入 a.xsd,使用:

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

我正在尝试通过以下方式通过Xerces执行此操作:

XMLSchemaFactory xmlSchemaFactory = new XMLSchemaFactory();
Schema schema = xmlSchemaFactory.newSchema(new StreamSource[] { new StreamSource(this.getClass().getResourceAsStream("a.xsd"), "a.xsd"),
                                                         new StreamSource(this.getClass().getResourceAsStream("b.xsd"), "b.xsd"),
                                                         new StreamSource(this.getClass().getResourceAsStream("c.xsd"), "c.xsd")});     
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new StringReader(xmlContent)));

但这无法正确导入所有三个架构,导致无法将名称“blah”解析为(n)“组”组件。

我已经使用Python成功验证了这一点,但是在Java 6.0Xerces 2.8.1中遇到了真正的问题。任何人都可以建议这里出了什么问题,或者更简单的方法来验证我的XML文档吗?


答案 1

因此,为了以防万一其他人在这里遇到同样的问题,我需要从单元测试中加载父架构(和隐式子架构) - 作为资源 - 以验证XML字符串。我使用Xerces XMLSchemFactory和Java 6验证器一起做到这一点。

为了通过包含正确加载子架构,我必须编写自定义资源解析器。代码可以在这里找到:

https://code.google.com/p/xmlsanity/source/browse/src/com/arc90/xmlsanity/validation/ResourceResolver.java

要使用解析程序,请在架构工厂中指定它:

xmlSchemaFactory.setResourceResolver(new ResourceResolver());

它将使用它通过类路径解析您的资源(在我的情况下来自src/main/resources)。欢迎对此提出任何意见...


答案 2

http://www.kdgregory.com/index.php?page=xml.parsing单个文档的多个架构”部分'

基于该文档的我的解决方案:

URL xsdUrlA = this.getClass().getResource("a.xsd");
URL xsdUrlB = this.getClass().getResource("b.xsd");
URL xsdUrlC = this.getClass().getResource("c.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=\"" +xsdUrlA.getPath() +"\"/>\n"
   + "<xs:include schemaLocation=\"" +xsdUrlB.getPath() +"\"/>\n"
   + "<xs:include schemaLocation=\"" +xsdUrlC.getPath() +"\"/>\n"
   +"</xs:schema>";
Schema schema = schemaFactory.newSchema(new StreamSource(new StringReader(W3C_XSD_TOP_ELEMENT), "xsdTop"));

推荐