在Groovy中正确地遍历XML和命名空间 [英] Properly iterating through XML with namespaces in Groovy

查看:235
本文介绍了在Groovy中正确地遍历XML和命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下xml代码:

 < soapenv:Envelope xmlns:soapenv =http:// schemas。 xmlsoap.org/soap/envelope/\"> 
< soapenv:Body>
< cms:RelatedConfigurationItemList xmlns:cms =some namespace>
< ConfigurationItem>
<名称>资料< / name>
< id>资料< / id>
< type>资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList>
< ConfigurationItem>
<名称>资料< / name>
< id>资料< / id>
< type>资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< ConfigurationItem>
<名称>资料< / name>
< id>资料< / id>
< type>资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< / ConfigurationItemList>
< / ConfigurationItem>
< ConfigurationItem>
<名称>其他资料< / name>
< id>其他资料< / id>
< type>其他资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList>
< ConfigurationItem>
<名称>其他资料< / name>
< id>其他资料< / id>
< type>其他资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< ConfigurationItem>
<名称>其他资料< / name>
< id>其他资料< / id>
< type>其他资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< / ConfigurationItemList>
< / ConfigurationItem>
< / cms:RelatedConfigurationItemList>
< / soapenv:Body>
< / soapenv:Envelope>

我想在Groovy中使用以下伪代码进行验证:

  def request = testRunner.testCase.getTestStepByName(relationship_request)
def resp = new File('H://test_xml.xml')
def cms_ns = new groovy.xml.Namespace(cms命名空间,'cms')
def soap_ns = new groovy.xml.Namespace(http://schemas.xmlsoap.org/soap / envelope /,'soapenv')
def root = new XmlSlurper()。parse(resp)

$ b $ def config_item = root [soap_ns.Envelope] [soap_ns.Body ] [cms_ns.RelatedConfigurationItemList] [ConfigurationItem]

config_item.each {
it.name.each {
it == db中对应的值?
else
die
}
}

但我似乎无法获得用于验证数据库响应定义的值(例如名称)的语法和逻辑权限。如果config_item声明是正确的,那么我可能对Groovy闭包知之甚少。另外,我不确定XML slurper或parser是否更合适,并且不能完全确定差异究竟是什么。希望这是对问题的充分描述。

解决方案

XmlSlurper在按需基础上工作,并且占用更少的内存。当您需要访问xml的许多节点时,通常使用XmlParser。或者,如果您只想读取xml的一个或两个节点,则使用Slurper。



这个例子应该可以帮助你理解XMLParser的工作原理。

在你的情况下,配置项声明和命名空间的用法在语法上是正确的,但它可能是使用XmlParser的理想选择,因为你可能正在验证xml的很多或所有组件。您可能会对使用闭包的元素访问感到困惑。这里是你的没有命名空间的例子来帮助你理解。

  xml ='''< Envelope> 
< Body>
< RelatedConfigurationItemList>
< ConfigurationItem>
<名称>顶级名称1< /名称>
< id>顶级id1< / id>
< type>顶级类型1< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList>
< ConfigurationItem>
< name> data1< / name>
< id> data1< / id>
< type> data1< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< ConfigurationItem>
< name> data2< / name>
< id> data2< / id>
< type> data2< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< / ConfigurationItemList>
< / ConfigurationItem>
< ConfigurationItem>
<名称>顶级名称2< /名称>
< id>顶级id2< / id>
< type>顶级类型2< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList>
< ConfigurationItem>
<名称>其他资料< / name>
< id>其他资料< / id>
< type>其他资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< ConfigurationItem>
<名称>其他资料< / name>
< id>其他资料< / id>
< type>其他资料< / type>
< relationship>是孩子的< / relationship>
< ConfigurationItemList />
< / ConfigurationItem>
< / ConfigurationItemList>
< / ConfigurationItem>
< / RelatedConfigurationItemList>
< / Body>
< / Envelope>'''



def Envelope = new XmlParser()。parseText(xml)

//用于访问顶层顶层配置项
Envelope.Body.RelatedConfigurationItemList.ConfigurationItem.each {
//将您的检查条件放在这里.. ==或任何其他
声明it.name.text ().contains(顶级名称)
assert it.id.text()。contains(Top level id)
assert it.type.text()。contains(Top level类型)
//内部子项配置项
it.ConfigurationItemList.ConfigurationItem.each {
assert it.name.text()。contains(data)
声明它.id.text()。contains(data)
assert it.type.text()。contains(data)
}
}


I have the following xml code:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <cms:RelatedConfigurationItemList xmlns:cms="some namespace">
         <ConfigurationItem>
            <name>data</name>
            <id>data</id>
            <type>data</type>
            <relationship>IS CHILD OF</relationship>
            <ConfigurationItemList>
               <ConfigurationItem>
                  <name>data</name>
                  <id>data</id>
                  <type>data</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
               <ConfigurationItem>
                  <name>data</name>
                  <id>data</id>
                  <type>data</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
            </ConfigurationItemList>
         </ConfigurationItem>
     <ConfigurationItem>
            <name>other data</name>
            <id>other data</id>
            <type>other data</type>
            <relationship>IS CHILD OF</relationship>
            <ConfigurationItemList>
               <ConfigurationItem>
                  <name>other data</name>
                  <id>other data</id>
                  <type>other data</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
               <ConfigurationItem>
                  <name>other data</name>
                  <id>other data</id>
                  <type>other data</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
            </ConfigurationItemList>
         </ConfigurationItem>
      </cms:RelatedConfigurationItemList>
   </soapenv:Body>
</soapenv:Envelope>

That I want to validate in Groovy using the following psuedo-code:

def request = testRunner.testCase.getTestStepByName( "relationship_request" )
def resp = new File('H://test_xml.xml')
def cms_ns = new groovy.xml.Namespace("namespace for cms",'cms')
def soap_ns = new groovy.xml.Namespace("http://schemas.xmlsoap.org/soap/envelope/",'soapenv')
def root = new XmlSlurper().parse(resp)


def config_item = root[soap_ns.Envelope][soap_ns.Body][cms_ns.RelatedConfigurationItemList][ConfigurationItem]

config_item.each{
    it.name.each{
        it == corresponding value in db?
        else
        die
    }
}

But I can't seem to get the syntax, logic right for trying to validate values defined (such as name) against a database response. If the config_item declaration is correct, then maybe I have a poor understanding of Groovy closures. Also, I'm not sure if XML slurper or parser is more appropiate and can't quite nail down what exactly the differences are. Hope this is an adequate description of the problem.

解决方案

XmlSlurper works on on-demand basis and is less memory intensive. When you need to access many nodes of the xml, you generally use an XmlParser. Or in case if you just want to read one or two nodes of an xml, you use Slurper.

This example should help you understand how XMLParser works.

In your case the config item declaration and namespace usage is syntactically correct but it might be ideal to use XmlParser as you might be validating many or all components of your xml. You might be getting confused regarding access of elements using closures. Here is your example without namespaces to help you understand.

   xml = '''<Envelope>
   <Body>
      <RelatedConfigurationItemList>
         <ConfigurationItem>
            <name>Top level name1</name>
            <id>Top level id1</id>
            <type>Top level type1</type>
            <relationship>IS CHILD OF</relationship>
            <ConfigurationItemList>
               <ConfigurationItem>
                  <name>data1</name>
                  <id>data1</id>
                  <type>data1</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
               <ConfigurationItem>
                  <name>data2</name>
                  <id>data2</id>
                  <type>data2</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
            </ConfigurationItemList>
         </ConfigurationItem>
     <ConfigurationItem>
            <name>Top level name2</name>
            <id>Top level id2</id>
            <type>Top level type2</type>
            <relationship>IS CHILD OF</relationship>
            <ConfigurationItemList>
               <ConfigurationItem>
                  <name>other data</name>
                  <id>other data</id>
                  <type>other data</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
               <ConfigurationItem>
                  <name>other data</name>
                  <id>other data</id>
                  <type>other data</type>
                  <relationship>IS CHILD OF</relationship>
                  <ConfigurationItemList/>
               </ConfigurationItem>
            </ConfigurationItemList>
         </ConfigurationItem>
      </RelatedConfigurationItemList>
   </Body>
</Envelope>'''



def Envelope = new XmlParser().parseText(xml)

//For accessing top level top level Configuration Item
Envelope.Body.RelatedConfigurationItemList.ConfigurationItem.each{
 //Put your check conditions here.. == or any other
 assert it.name.text().contains("Top level name")
 assert it.id.text().contains("Top level id")
 assert it.type.text().contains("Top level type")
 //Inner children configuration items
 it.ConfigurationItemList.ConfigurationItem.each{
     assert it.name.text().contains("data")
     assert it.id.text().contains("data")
     assert it.type.text().contains("data")
 }       
}

这篇关于在Groovy中正确地遍历XML和命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆