我必须编写一些代码来处理读取和验证XML文档,这些文档在其根元素中使用version属性来声明版本号,如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Junk xmlns="urn:com:initech:tps"
xmlns:xsi="http://www3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:com:initech.tps:schemas/foo/Junk.xsd"
VersionAttribute="2.0">
有一堆嵌套模式,我的代码有org.w3c.dom.ls.LsResourceResolver
来确定要使用的模式,实现此方法:
LSInput resolveResource(String type,
String namespaceURI,
String publicId,
String systemId,
String baseURI)
架构的早期版本已将架构版本嵌入到命名空间中,因此我可以使用namespaceURI和systemId来决定提供哪个架构。现在版本号已切换到根元素中的属性,我的解析器无法访问该元素。我如何在LsResourceResolver
中找出XML文档的版本?
答案 0 :(得分:3)
我的建议
从已解析的文档构建DOMSource
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(args[0]));
domSource = new DOMSource(document);
答案 1 :(得分:3)
我之前从未处理过架构版本,也不知道涉及到什么。当版本是命名空间的一部分时,我可以将所有模式放在一起并让它们被整理出来,但是根元素和版本中的版本在版本之间共享,无法从XML中读取版本信息< em>在开始SAX解析之前。
我将做一些非常类似于Pangea建议的内容(从我那里获得+1),但我无法完全遵循这些建议,因为文档太大而无法将其全部读入内存,甚至一次。通过使用STAX,我可以最大限度地减少从文件中获取版本所需的工作量。请参阅此DeveloperWorks文章"Screen XML documents efficiently with StAX":
XML文档的筛选或分类是一个常见问题, 特别是在XML中间件中。将XML文档路由到特定的 处理器可能需要分析文档类型和 文件内容。这里的问题是获得所需 来自文档的信息具有最小的开销。 传统的解析器(如DOM或SAX)不太适合这种情况 任务。例如,DOM解析整个文档并构造一个 在将控制权返回给内存之前,在内存中完成文档树 客户。甚至是使用延迟节点扩展的DOM解析器,因此 能够部分解析文档,有很高的资源需求 因为文档树必须至少部分构造在 记忆。这对于筛选目的来说是不可接受的。
获取版本信息的代码如下所示:
def map = [:]
def startElementCount = 0
def inputStream = new File(inputFile).newInputStream()
try {
XMLStreamReader reader =
XMLInputFactory.newInstance().createXMLStreamReader(inputStream)
for (int event; (event = reader.next()) != XMLStreamConstants.END_DOCUMENT;) {
if (event == XMLStreamConstants.START_ELEMENT) {
if (startElementCount > 0) return map
startElementCount += 1
map.rootElementName = reader.localName
for (int i = 0; i < reader.attributeCount; i++) {
if (reader.getAttributeName(i).toString() == 'VersionAttribute') {
map.versionIdentifier = reader.getAttributeValue(i).toString()
return map
}
}
}
}
} finally {
inputStream.close()
}
然后我可以使用版本信息来确定要使用的解析器以及要在SaxFactory上设置的架构文档。