XML验证 - 使用多个xsd文件

17

我有两个xsd文件用于验证xml。但问题是我的代码只使用了一个xsd。如何在下面的代码中使用另一个xsd?我不知道应该把/呼叫第二个xsd文件放在哪里。

             private void validate(File xmlF,File xsd1,File xsd2) {
                    try {
                        url = new URL(xsd.toURI().toString());//  xsd1
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }


                    source = new StreamSource(xml); // xml
                    try {
                        System.out.println(url);
                        schema = schemaFactory.newSchema(url);
                    } catch (SAXException e) {
                        e.printStackTrace();
                    }
                    validator = schema.newValidator();
                    System.out.println(xml);
                    try {
                        validator.validate(source);
                    } catch (SAXException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

4
你已经尝试过newSchema(Source[])了吗? - Michael-O
是的,我尝试过那种方式。它不起作用,可能是因为Source[]用于xml。我们无法将xsd强制转换为source。 - freepublicview
2
就像之前关于这个XML验证项目的问题一样,我想指向SSCCE。你的代码片段远未完成,因为你在方法外定义变量等。注意你提问的方式,有助于我们帮助你。 - Wivani
1
可能是针对多个XSD模式进行验证的XML的重复问题。 - rogerdpack
1个回答

33

在SO或Google上搜索时有很多相关结果。其中之一是这个问题,作者找到了自己的解决方案,并报告以下代码来将多个XSD添加到验证器:

Schema schema = factory().newSchema(new Source[] {
  new StreamSource(stream("foo.xsd")),
  new StreamSource(stream("Alpha.xsd")),
  new StreamSource(stream("Mercury.xsd")),
});

然而,当直接使用 InputStreamStreamSource 时,解析器无法加载任何引用的 XSD 文件。例如,如果文件 xsd1 导入或包含第三个文件(不是 xsd2),则模式创建将失败。您应该设置系统标识符(setSystemId),或者更好的方法是使用 StreamSource(File f) 构造函数。

根据您的示例代码进行调整:

try {
  schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  schema = schemaFactory.newSchema(new Source[] {
    new StreamSource(xsd1), new StreamSource(xsd2)
  });
} catch (SAXException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

注意:

如果使用classpath资源,我更喜欢使用StreamSource(String systemId)构造函数(而不是创建File):

new StreamSource(getClass().getClassLoader().getResource("a.xsd").toExternalForm());

这与我上面的问题完全相同。 - Michael-O
6
这是你在评论中提供的相同解决方案。这就是为什么我点赞了你的评论。然而,OP遇到了实现上的困难; 我之前回答他的问题时已经在我的Eclipse中准备好了代码,并简单地调整了它以展示如何使用Source[]。希望没有什么不满呢? - Wivani
@Michael-O这就是为什么你应该将它作为答案发表,而不是评论。 - Line
1
new StreamSource(getClass().getClassLoader().getResource("a.xsd").toExternalForm()) 解决了我的问题,谢谢! - RoBeaToZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接