SOAPUI Groovy 脚本插入具有自定义值的 xml 节点

SOAPUI Groovy script inserting xml node with custom value

所以我有一个步骤需要一些数字 ID 并在数据库中查找它们的值。我希望能够编辑响应 xml 并包含从数据库中获取的值以提高可读性。

我想出了如何将 xml 节点添加到 xmlHolder 中,但是我似乎无法在节点中放入值。

这是最接近的'seemingly'工作代码:

def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)

def dbResult = testRunner.testCase.testSteps["getNames"].getResponseContent()
def xmlOfferNames = groovyUtils.getXmlHolder(dbResult)

def names = xmlOfferNames.getNodeValues("//NAME")
def codes = xmlOfferNames.getNodeValues("//ID")

def recs = groovyUtils.getXmlHolder("Item#Reply")

def insert
for(int i=0; i<names.size(); i++){
    for(node in recs.getDomNodes("//Item[ID='"+codes[i]+"']")){
        //insert = '<NAME>'+names[i]+'</NAME>' //nothing is taking strings
        //node.appendNode(new Node(node, 'NAME', names[i])) //dne constructor
        insert = node.getOwnerDocument().createElementNS(node.getNamespaceURI(), "NAME")
        //log.info names[i]
        insert.setNodeValue(names[i])
        //log.info insert.metaClass.methods*.name.sort().unique()
        node.insertBefore(insert , node.getFirstChild())
    }
}

recs.updateProperty()
log.info recs.getXml()

然而,当它打印出生成的 xml 时,我只有空的 <NAME/> 标签,没有任何价值。

我试过使用 insert.setTextContent(),但它显示 java.long.RuntimeException: DOM Level 3 Not implemented。我没有看到任何其他我可以用来设置值的东西。

(半相关,奇怪的是它也没有更新我步骤中的 xml,但我还没有开始研究它)

不要使用 holder 修改您的 XML,请尝试使用 XmlSlurper:

import groovy.xml.XmlUtil
def xml = '''<sample>
    <RetailRecommendation>
        <OfferCode>a1</OfferCode>
    </RetailRecommendation>
    <RetailRecommendation>
        <OfferCode>b2</OfferCode>
    </RetailRecommendation>
    <RetailRecommendation>
        <OfferCode>a1</OfferCode>
        <OfferCode>ac3</OfferCode>
    </RetailRecommendation>
</sample>
'''

def recs = new XmlSlurper().parseText(xml)

def names = ['kilo','mega','giga']
def codes = ['a1','b2','ac3']

// for each name
names.eachWithIndex{ name, i ->

     // find all OfferCode elements inside RetailRecommendation
     // where value is in codes[i] array
    recs.RetailRecommendation.'**'.findAll { node ->
        node.name() == 'OfferCode' && node.text() == codes[i] 
    }.each{ elem ->  // for each element...
        // create the new node to add
        def nodeToAdd = new XmlSlurper().parseText('<OFFER_NAME>' + name + '</OFFER_NAME>')
        // and append the node to your element
        elem.parent().appendNode(nodeToAdd)
    }
}

log.info XmlUtil.serialize(recs)

这导致:

<sample>
   <RetailRecommendation>
      <OfferCode>a1</OfferCode>
      <OFFER_NAME>kilo</OFFER_NAME>
   </RetailRecommendation>
   <RetailRecommendation>
      <OfferCode>b2</OfferCode>
      <OFFER_NAME>mega</OFFER_NAME>
   </RetailRecommendation>
   <RetailRecommendation>
      <OfferCode>a1</OfferCode>
      <OfferCode>ac3</OfferCode>
      <OFFER_NAME>kilo</OFFER_NAME>
      <OFFER_NAME>giga</OFFER_NAME>
   </RetailRecommendation>
</sample>

在您的代码中,您可以继续使用 holder 来获取 namescodes,但更改您修改响应的方式,总之可能类似于:

import groovy.xml.XmlUtil

def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)

def dbResult = testRunner.testCase.testSteps["getOfferNames"].getResponseContent()
def xmlOfferNames = groovyUtils.getXmlHolder(dbResult)

def names = xmlOfferNames.getNodeValues("//NAME")
def codes = xmlOfferNames.getNodeValues("//OFFERCODE1")

def recs = new XmlSlurper().parseText(context.expand('${getRetailRecommendation#Response}'))

// for each name
names.eachWithIndex{ name, i ->

     // find all OfferCode elements inside RetailRecommendation
     // where value is in codes[i] array
    recs.RetailRecommendation.'**'.findAll { node ->
        node.name() == 'OfferCode' && node.text() == codes[i] 
    }.each{ elem ->
        // for each node found it
        def nodeToAdd = new XmlSlurper().parseText('<OFFER_NAME>' + name + '</OFFER_NAME>')
        elem.parent().appendNode(nodeToAdd)
    }
}

log.info XmlUtil.serialize(recs)

希望这对您有所帮助,

事实证明你不能只向元素添加一个字符串,你必须制作一个文本节点。

insert.appendChild(node.getOwnerDocument().createTextNode(names[i]))