如何使用Groovy XmlParser获得XML根元素属性而无需对XML进行“双重解析”

时间:2018-07-12 14:39:09

标签: xml groovy

此简化的代码正常工作:

    static stringXML = '''<?xml version='1.0' encoding='UTF-8'?>
    <ftc:FATCA_OECD xsi:schemaLocation='urn:oecd:ties:fatca:v1 FatcaXML_v1.1.xsd' version='1.1' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:sfa='urn:oecd:ties:stffatcatypes:v1' xmlns:ftc='urn:oecd:ties:fatca:v1'>
    <ftc:MessageSpec>Spec</ftc:MessageSpec>
</ftc:FATCA_OECD>'''
    static void main(args) {
    //NAMESPACE UNAWARE PARSING
        def rep = new XmlParser(false,false).parseText(stringXML)
        def attrMap = rep.attributes()
        attrMap.each {k,v ->
            println "$k, $v"
        }
    //NAMESPACE AWARE PARSING
        rep = new XmlParser().parseText(stringXML)
        def ftc = new groovy.xml.Namespace(attrMap['xmlns:ftc'])
        println rep[ftc.MessageSpec].text()
    }
}

并产生以下正确输出:

xsi:schemaLocation,urn:oecd:ties:fatca:v1 FatcaXML_v1.1.xsd

版本1.1

xmlns:xsi,http://www.w3.org/2001/XMLSchema-instance

xmlns:sfa,缸:oecd:tie:stffatcatypes:v1

xmlns:ftc,:oecd:ties:fatca:v1

规格

问题是,我已经在相当广泛的代码中使用了名称空间感知解析,并且我希望保留它。...

因此,我必须像上面的代码中那样同时使用不了解名称空间和名称空间感知的解析

您知道吗,如何产生相同的结果而无需对整个.xml(.xml相当大)进行两次解析,或者仅提取.xml的根元素,而不是使用名称空间感知的解析。...

1 个答案:

答案 0 :(得分:0)

通常,您必须知道xml的命名空间,以便采用必需元素的代码如下所示:

def stringXML = """<?xml version='1.0' encoding='UTF-8'?>
    <ftc:FATCA_OECD xsi:schemaLocation='urn:oecd:ties:fatca:v1 FatcaXML_v1.1.xsd' version='1.1' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:sfa='urn:oecd:ties:stffatcatypes:v1' xmlns:ftc='urn:oecd:ties:fatca:v1'>
    <ftc:MessageSpec>Spec</ftc:MessageSpec>
</ftc:FATCA_OECD>"""
def rep = new XmlParser().parseText(stringXML)

def ftc_v1 = new groovy.xml.Namespace('urn:oecd:ties:fatca:v1')
println rep[ftc_v1.MessageSpec].text()

或者您可以采用根元素的名称空间并访问具有相同名称空间的子元素MessageSpec

def ftc_vx = new groovy.xml.Namespace( rep.name().getNamespaceURI() )
println rep[ftc_vx.MessageSpec].text()

最后,这意味着您不必关心名称空间,可以使用XmlSlurper来访问忽略名称空间的元素:

rep = new XmlSlurper().parseText(stringXML)
println rep.MessageSpec.text()