如何迭代XML以在soapUI中创建Xpath?

时间:2012-05-21 20:44:37

标签: xpath groovy soapui loops

我正在尝试使用一系列AMF请求在soapUI中为我的API设置负载测试,但是我无法弄清楚如何使用这样的XML响应进行属性传输:

<flex.messaging.io.amf.ASObject serialization="custom">
  <unserializable-parents/>
  <map>
    <default>
      <loadFactor>0.75</loadFactor>
      <threshold>48</threshold>
    </default>
    <int>64</int>
    <int>28</int>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <null/>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <object-array/>
    <string>key</string>
    <flex.messaging.io.amf.ASObject serialization="custom">
      <unserializable-parents/>
      <map>
        <default>
          <loadFactor>0.75</loadFactor>
          <threshold>12</threshold>
        </default>
        <int>16</int>
        <int>3</int>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
      </map>
      <flex.messaging.io.amf.ASObject>
        <default>
          <inHashCode>false</inHashCode>
          <inToString>false</inToString>
          <namedType>package/class</namedType>
        </default>
      </flex.messaging.io.amf.ASObject>
    </flex.messaging.io.amf.ASObject>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <flex.messaging.io.amf.ASObject serialization="custom">
      <unserializable-parents/>
      <map>
        <default>
          <loadFactor>0.75</loadFactor>
          <threshold>12</threshold>
        </default>
        <int>16</int>
        <int>5</int>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
      </map>
      <flex.messaging.io.amf.ASObject>
        <default>
          <inHashCode>false</inHashCode>
          <inToString>false</inToString>
          <namedType>package/class</namedType>
        </default>
      </flex.messaging.io.amf.ASObject>
    </flex.messaging.io.amf.ASObject>
    <string>guid</string>
    <string>818f40db-c217-46ed-a6a2-7c830d894a95</string>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <null/>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
  </map>
  <flex.messaging.io.amf.ASObject>
    <default>
      <inHashCode>false</inHashCode>
      <inToString>false</inToString>
      <namedType>package/class</namedType>
    </default>
  </flex.messaging.io.amf.ASObject>
</flex.messaging.io.amf.ASObject>

因为我没有使用soapUI Pro,所以我无法访问xpath向导。有没有办法使用Property transfer或Groovy Script访问此节点?

1 个答案:

答案 0 :(得分:0)

你可以使用XmlSlurper来访问这两个:

def src = '''<flex.messaging.io.amf.ASObject serialization="custom">
            |  <unserializable-parents/>
            |  <map>
            |    <default>
            |      <loadFactor>1.00</loadFactor>
            |      <threshold>50</threshold>
            |    </default>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <object-array/>
            |    <string>Not what I need</string>
            |    <string>This is the KEY I'm looking for</string>
            |    <string>This is the VALUE I need to pass to the next test step</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <null/>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <null/>
            |    <string>Not what I need</string>
            |    <null/>
            |  </map>
            |</flex.messaging.io.amf.ASObject>'''.stripMargin()

def aso = new XmlSlurper().parseText( src )

def (key,value) = aso.map.string[6..7]*.text()

println "  key = $key"
println "value = $value"

这感觉有点难以编码&#39;但我无法看到这些值是如何以编程方式定位的: - (


修改

鉴于您发布的新XML,这似乎适用于此实例:

println aso.map.children()[ 3..-1 ]    // Strip out the initial default and ints
       .collate( 2 )                   // Group the key/value pairs
       .findAll { 
         it[ 0 ].text() == 'guid'      // find all that have 'guid' as element 0
       }
       .collectEntries { it*.text() }  // convert this into a map

并打印:

[guid:818f40db-c217-46ed-a6a2-7c830d894a95]

但是,更彻底的depthFirst算法可能是扫描所有可能输入的更可靠的方法(我不知道ASObject序列化,所以我不知道这是否适用于此实例)


编辑2

当您遇到没有collate方法(1.8.6)的Groovy版本时,您可以使用传统的for循环执行类似的操作:

def aso = new XmlSlurper().parseText( src ).map.children()
String guid = null
for( i = 3 ; i < aso.size() ; i += 2 ) {
  if( aso[ i ] == 'guid' ) {
    guid = aso[ i + 1 ]
    break
  }
}
println guid