java - 解析哪个版本的 XML 模式用于具有版本属性的 XML 文档

标签 java xml xsd sax jaxp

我必须编写一些代码来处理读取和验证在其根元素中使用版本属性来声明版本号的 XML 文档,如下所示:

<?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 文档的版本?

最佳答案

在此之前,我从未处理过模式版本,也不知道涉及什么。当版本是命名空间的一部分时,我可以将所有模式放在一起并让它们得到整理,但是由于根元素中的版本和跨版本共享的命名空间,无法绕过从 XML < em>在 开始SAX 解析之前。

我打算做一些与 Pangea 建议非常相似的事情(从我那里得到 +1),但我不能完全遵循建议,因为文档太大而无法将其全部读入内存,即使一次也不行。通过使用 STAX,我可以最大限度地减少从文件中获取版本的工作量。请参阅这篇 DeveloperWorks 文章,"Screen XML documents efficiently with StAX" :

The screening or classification of XML documents is a common problem, especially in XML middleware. Routing XML documents to specific processors may require analysis of both the document type and the document content. The problem here is obtaining the required information from the document with the least possible overhead. Traditional parsers such as DOM or SAX are not well suited to this task. DOM, for example, parses the whole document and constructs a complete document tree in memory before it returns control to the client. Even DOM parsers that employ deferred node expansion, and thus are able to parse a document partially, have high resource demands because the document tree must be at least partially constructed in memory. This is simply not acceptable for screening purposes.

获取版本信息的代码如下所示:

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 上设置的模式文档。

关于java - 解析哪个版本的 XML 模式用于具有版本属性的 XML 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12007079/

相关文章:

c# - 如何解析xs :date with NodaTime?

java - Neo4j SDN 预填充实体

java - 如何配置 Spring Data 在保存到 Mongo DB 时使用对象的字符串版本?

Android 和 XML

xml - XSD:缺失元素的默认值

在 Visual Studio IDE 中使用 XSD 进行 XML 验证

java - 尝试在 Tomcat 服务器上运行 Web 应用程序但无法运行

java - Android - Firebase - 提示群聊名称

android - 嵌套 View Flipper 布局

java - JAXBContextFactory hell - java.lang.ClassNotFoundException : com. ibm.xml.xlxp2.jaxb.JAXBContextFactory