zoukankan      html  css  js  c++  java
  • SoapUI中XML解析

    From http://www.robert-nemet.com/2011/11/groovy-xml-parsing-in-soapui.html

    Introduction

        Since soapUI allows users to add Groovy scripts in large number of places ( property expansions, setup /teardown scripts, listeners, test step, etc... ) users can use any technology to reach to the goal. Lets look at those which can make our life easier when it comes to XML parsing.

    soapUI XML Support

        Old way would be soapUI way or using GroovyUtils from soapUI. Its goal is to simplify scripting and it can be instantiate from any Groovy script in soapUI, with:

    where context is available in any Groovy script in soapUI. Lets look at GroovyUtils:

    def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
    GroovyUtils Methods
    expand(property)  
    returns value of property, if there are property expansions they are expanded. 
    extractErrorLineNumber(error) 
    returns line number where error occurred
    getProjectPath() 
     
    returns path to project file           
    getXml(node)
    returns xml as a string from passed node
    getXmlHolder(xmlPropertyOrString) 
    returns XmlHolder as a result of parsing passed Xml string           
    registerJdbcDriver(driver) 
    register JDBC driver for use in Groovy script
    setPropertyValue(testStep, property, value) 
    sets a value for given test step property


    This time getXmlHolder is one that does what we need. Pars a given string as XML and returns object which we can use to manipulate with it.

    XmlHolder Methods
    declareNamespace(prefix, uri)  declare namespace prefix and URI
    getDomNode(xpath)            
    returns a DOM node pointed by XPath expression 
    getDomNodes(xpath)  returns an array of DOM nodes pointed by XPath expression 
    getNamespaces()  returns a Map of namespaces 
    getNodeValue(xpath)  returns a value of node specified by XPath expression
    getNodeValues(xpath)  returns an array of values specified by XPath expression
    getPrettyXml()            
    returns a formatted XML 
    getXml()      
    returns a XML 
    getXmlObject() returns a XmlBean Object 
    removeDomNodes(xpath) removes a nodes specified by XPath expression 
    setNodeValue(xpath, value)  set a node value  
    updateProperty()  if a XmlHolder is created from test step property this updates that property 
    updateProperty(prettyPrint) 
                
    if a XmlHolder is created from test step property this updates that property with well formatted XML 


    Few Examples

    Assume you have response:

    For this examples I added a Properties Test Step  with property response.

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sim="http://www.example.org/SimpleSocialSOA/">
       <soapenv:Header/>
       <soapenv:Body>
          <sim:LoginResponse>
             <id>4456643453</id>
          </sim:LoginResponse>
       </soapenv:Body>
    </soapenv:Envelope> 



    1. Parsing XML

    According to that to get id from response you can do:

    def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
    def holder = groovyUtils.getXmlHolder("Properties#response")
    log.info holder.getNodeValue("//id")
    log.info holder['//id']


    notice two ways to get node value with getNodeValue method and with [] operator. Difference is that getNodeValue will return first value that can be found with set XPath, while [] operator returns a array of values.
    If you assume that response is like:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sim="http://www.example.org/SimpleSocialSOA/">
       <soapenv:Header/>
       <soapenv:Body>
          <sim:LoginResponse>
             <id>4456643453</id>
             <id>4456643452</id>
             <id>4456643451</id>
             <id>4456643450</id>
          </sim:LoginResponse>
       </soapenv:Body>
    </soapenv:Envelope>

    Than this script:

    def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
    def holder = groovyUtils.getXmlHolder("Properties#response")
    log.info holder.getNodeValue("//id")
    for( node in holder['//id'] )
     log.info node

    will produce result like this:


    2. Updating XML

    Response as above and we do:

    def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
    def holder = groovyUtils.getXmlHolder("Properties#response")
    holder.setNodeValue("//id", "aaaaa")
    for( node in holder['//id'] )
     log.info node
    def holder2 = groovyUtils.getXmlHolder("Properties#response")
    holder2.getNodeValue("//id")
    for( node in holder2['//id'] )
     log.info node

     Result is:


    from this we can learn:

    • if there are several nodes as result of XPath expression only first's node value will be changed with setNodeValue
    • setting node value is not enough to update property value, we forgot to use updateProperty method
    Correct Groovy script would be:
    def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
    def holder = groovyUtils.getXmlHolder("Properties#response")
    holder.setNodeValue("//id", "aaaaa")
    for( node in holder['//id'] )
     log.info node
    holder.updateProperty()
    def holder2 = groovyUtils.getXmlHolder("Properties#response")
    holder2.getNodeValue("//id")
    for( node in holder2['//id'] )
     log.info node


    Instead of using:

    holder.setNodeValue("//id", "aaaaa")

    you can use also:

    holder["//id"] = "aaaaa"

    And if XmlNode is created from property as in example above use updateProperty method to apply your changes to property or use GroovyUtils.setPropertyValue method. 



    Groovy XML

    There are three classes built in Groovy for processing XML: XMLParser, XMLSlurper and DOMCategory. Best practice is to use XMLSlurper in soapUI. Reason is that it have smallest memory footprint from all three. I would no go in depths for those, you can read here XML processing.
    This for example:

    import groovy.xml.StreamingMarkupBuilder
    def response = context.testCase.testSteps['Properties'].properties['response'].value
    def responseXml = new XmlSlurper().parseText(response)
    responseXml.breadthFirst().each {
     def v = it.toString()
     if ( it.name() == 'id')
        it.replaceBody("$v XX")
     }

    appends " XX" to values of all id nodes.

    Generally it is easier to use GroovyUtils but if you are familiar or invest some time in XmlSlurper you can get better results and more flexible scripts.

  • 相关阅读:
    16.10.16学到的JAVA知识
    参数类型转换求和(JAVA)
    大道至简第一篇读后感之愚公移山(伪代码)
    First
    18.10.22 luoguP3374 【模板】树状数组 1
    18.10.16 luoguP3372 线段树模板-区间更新值&求和(POJ3468 A Simple Problem with Integers)
    18.10.16 POJ 2528 Mayor's posters(线段树+离散化)
    18.10.15 POJ 2182 Lost Cows(线段树)
    18.10.10 数算作业-字符串
    18.10.9 不好做的最长上升子序列(nlogn树状数组解LIS)
  • 原文地址:https://www.cnblogs.com/alansheng/p/4843841.html
Copyright © 2011-2022 走看看