实现LSResourceResolver以递归读取一组XSD文件。
实现LSResourceResolver以递归读取一组XSD文件。
我需要从jar中加载XSD文件,因此实现了LSResourceResolver,如下所示:
Source schemaFile = new StreamSource(getClass().getClassLoader().getResourceAsStream("resources/xsd/root/maindoc/MainSchema.xsd")); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); schemaFactory.setResourceResolver(new LSResourceResolver(){ @Override public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { LSInput input = new DOMInputImpl(); String filePath = getNormalizedPath("resources/xsd/root/maindoc/", systemId); InputStream stream = getClass().getClassLoader().getResourceAsStream(filePath); input.setPublicId(publicId); input.setSystemId(systemId); input.setBaseURI(baseURI); input.setCharacterStream(new InputStreamReader(stream)); return input; } }); Schema schema = schemaFactory.newSchema(schemaFile);
这样的实现可以成功解析主模式中的链接,但无法解析引用文档中的链接。
通过引用文档的调用,我收到了非空的baseURI参数,但在我的情况下,其值类似于"file:///var/xxx/yyy.xsd",因此似乎无法从此和systemId构造有效路径。
我有什么遗漏吗?是否可能使解析器递归工作?
当然,可以通过将模式展开来解决这个问题,但我不太喜欢这种方法。
问题的出现原因是在解析XSD文件时,实现LSResourceResolver接口过于繁琐,而且可能无法处理递归包含的情况。文章中提到,使用newSchema(URL schema)方法可能是更好的解决方法。使用URL接口的优点是可以简单地从文件和资源中构建URL,而无需自定义LSResourceResolver,并且缓冲由实现处理。然而,URL接口不能优雅地从实际流(标准输入或网络连接)中读取模式。大多数应用程序实际上是从主机文件系统或应用程序资源中读取模式。文章给出了一个示例代码,展示如何使用URL接口来读取模式,并提到了自定义的错误处理程序,以便在遇到错误时抛出异常。最后,文章总结了使用URL方法的优点:简单、优雅和有效。