1

我有以下 xml 代码:

<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>

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

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
    }
}

但是我似乎无法获得正确的语法和逻辑来尝试针对数据库响应验证定义的值(例如名称)。如果 config_item 声明是正确的,那么可能我对 Groovy 闭包的理解很差。此外,我不确定 XML slurper 或解析器是否更合适,也无法确定到底有什么区别。希望这是对问题的充分描述。

4

3 回答 3

2

XmlSlurper 按需工作,内存占用较少。当需要访问 xml 的多个节点时,一般使用 XmlParser。或者,如果您只想读取 xml 的一个或两个节点,您可以使用 Slurper。

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

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

   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")
 }       
}
于 2012-07-24T06:20:05.443 回答
1

你几乎拥有它...

如果您使用XmlParser(如 Vamsi 建议的那样)而不是XmlSlurper,您会得到:

def cms_ns = new groovy.xml.Namespace("some namespace",'cms')
def soap_ns = new groovy.xml.Namespace("http://schemas.xmlsoap.org/soap/envelope/",'soapenv')
def root = new XmlParser().parse(resp)

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

您不需要使用Envelope标签进行区分,因为这是根节点,因此它被认为已经加载。

于 2012-07-24T09:10:57.867 回答
0

XmlSlurper 很好。尝试以下操作:

def configItem = root.'**'.findAll{
   it.name()=='ConfigurationItem'
}

configItem.each{
   // check data here
}

这应该递归地检查所有配置项,假设这就是你想要完成的。

于 2012-07-24T03:09:27.430 回答