简体   繁体   English

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

[英]SOAPUI Groovy script inserting xml node with custom value

So I've got a step that takes some numerical ids & looks up their values in a database. 因此,我采取了一些步骤,需要一些数字id并在数据库中查找它们的值。 I want to be able to edit the response xml & include the values gotten from the database for readability purposes. 我希望能够编辑响应xml并包括从数据库中获取的值,以提高可读性。

I figured out how to add the xml node into the xmlHolder, however I can't seem to put a value inside the node. 我想出了如何将xml节点添加到xmlHolder中,但是我似乎无法在该节点内放置值。

This is the closest 'seemingly' working code: 这是最接近的“看似”工作代码:

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

However, when it prints out the generated xml I just have empty <NAME/> tags, with no value. 但是,当它打印出生成的xml时,我只有空的<NAME/>标记,没有任何值。

I've tried to use insert.setTextContent() but it says java.long.RuntimeException: DOM Level 3 Not implemented . 我尝试使用insert.setTextContent()但是它说java.long.RuntimeException: DOM Level 3 Not implemented I don't see anything else I could use to set the value. 我看不到其他可用来设置值的东西。

(semi-relatedly, it oddly doesn't update the xml in my step either, but I haven't started researching that yet) (半相关,奇怪的是,它也不会在我的步骤中更新xml,但我尚未开始进行研究)

Instead of using holder to modify your XML try using XmlSlurper : 可以使用XmlSlurper来代替使用holder来修改XML

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)

This results in: 结果是:

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

Inside your code you can keep using holder to get the names and codes but change the way you modify the response, all together could be something like: 在您的代码内部,您可以继续使用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)

Hope this helps, 希望这可以帮助,

事实证明,您不能只向元素添加字符串,而必须创建一个文本节点。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM