我需要验证以编程方式生成的XML Schema Instance(XSD)文档,以便我使用以下Java代码段,它可以正常工作:
SchemaFactory factory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema xsdSchema = factory.newSchema( // Reads URL every time...
new URL("http://www.w3.org/2001/XMLSchema.xsd"));
Validator xsdValidator = xsdSchema.newValidator();
xsdValidator.validate(new StreamSource(schemaInstanceStream));
但是,当我在本地保存XML Schema definition file并以这种方式引用它时:
Schema schema = factory.newSchema(
new File("test/xsd/XMLSchema.xsd"));
失败,出现以下异常:
org.xml.sax.SAXParseException:schema_reference.4:无法读取架构文档'file:/Users/foo/bar/test/xsd/XMLSchema.xsd',因为1)找不到该文档; 2)文件无法阅读; 3)文档的根元素不是< xsd:schema>。
通过在exists()
对象上执行canRead()
和File
断言,我确保文件存在且可读。我还使用几个不同的实用程序(Web浏览器,wget)下载了该文件,以确保没有损坏。
当我从HTTP URL生成架构时,我知道为什么我可以验证XSD实例文档但是在尝试从具有相同内容的本地文件生成时我得到了上述异常?
[编辑]
详细说明一下,我尝试了多种形式的factory.newSchema(...)
使用Readers和InputStreams(而不是直接使用File),但仍然得到完全相同的错误。此外,我在使用它或各种输入流之前已经转储了文件内容以确保它是正确的。相当令人烦恼。
事实证明,XML Schema引用了另外三个文件,它们也必须存储在本地,而XMLSchema.xsd
包含一个必须更改schemaLocation
属性的import语句。以下是必须保存在同一目录中的文件:
schemaLocation
更改为“xml.xsd
”。感谢@Blaise Doughan和@Tomasz Nurkiewicz的提示。
答案 0 :(得分:4)
我假设您正在尝试加载XMLSchema.xsd。另请下载XMLSchema.dtd和datatypes.dtd并将它们放在同一目录中。这应该会让你更进一步。
答案 1 :(得分:2)
<强>更新强>
XMLSchema.xsd是否通过不在本地文件系统上的相对路径导入任何其他模式?
您的工作目录中的相对路径可能不正确。尝试输入完全限定的路径,以消除无法找到文件的可能性。
org.xml.sax.SAXParseException:schema_reference.4:无法读取 架构文档'file:/Users/foo/bar/test/xsd/XMLSchema.xsd',因为 1)找不到文件; 2)文件无法读取; 3) 文档的根元素不是。