1

I'm trying to modify a SOAP Request by adding a duplicate child node with different value.

This is what I have so far:

Request:

<soapenv:Envelope xlmns:ns1 = "..." xlmns:ns2 = "..." xlmns:ns3 = "..." xlmns:ns4 = "...">
   <soapenv:Body>
       <ns2:OperationName>
          <ns3:CuteN>77777</ns3:CuteN>
          <ns3:RaveN>666</ns3:RaveN>
       </ns2:OperationName>
   </soapenv:Body>
</soapenv:Envelope>

Request to be modified as: (fill the xml tags & add another tag <RaveN></RaveN> with a value)

<soapenv:Envelope xlmns:ns1 = "..." xlmns:ns2 = "..." xlmns:ns3 = "..." xlmns:ns4 = "...">
   <soapenv:Body>
       <ns2:OperationName>
          <ns3:CuteN>77777</ns3:CuteN>
          <ns3:RaveN>666</ns3:RaveN>
          <ns3:RaveN>888</ns3:RaveN>
       </ns2:OperationName>
    </soapenv:Body>
 </soapenv:Envelope>

Code used:

/* Groovy Utilities Declaration */
def groovyUtils = new ns4.eviware.soapui.support.GroovyUtils(context)

/* Request Holder Setup */
def request      = context.expand('${RequestStepName#Request}')
def requestHolder    = groovyUtils.getXmlHolder("request")

/* Declaring Namespaces */
requestHolder.namespaces["soapenv"] = "http://schemas.xmlsoap.org/soap/envelope/"
requestHolder.namespaces["ns2"]     = "..."
requestHolder.namespaces["ns3"]     = "..."
requestHolder.namespaces["ns4"]     = "..."

/* Set few string names */
def soapEnvXString       = "//soapenv:Envelope"
def soapBodyXString      = "/soapenv:Body"
def operXString          = "/ns2:OperationName"
def raveNumXString       = "/ns3:RaveNum"

/* create object of Request nodes */
def parentNode       = requestHolder.getDomNode(soapEnvXString + soapBodyXString + operXString)

def reqRaveNumTwo = "888"

if(reqRaveNumTwo != null && reqRaveNumTwo != "")
{
    /* create new node */   
    def secondRaveNumNode = new XmlSlurper(false,false).parseText("""<ns3:RaveNum>${reqRaveNumTwo}</ns3:RaveNum>""")
    parentNode.appendNode(secondRaveNumNode)
}

/* Update the request holder properties */
requestHolder.updateProperty(true)

Error:

groovy.lang.MissingMethodException: No signature of method: org.apache.xmlbeans.impl.store.Xobj$ElementXobj.appendNode() is applicable for argument types: (groovy.util.slurpersupport.NodeChild) values: [888]

I know I'm missing something here, this is my 3rd day of Groovy deep-dive. Any help will be much appreciated, Thanks in advance!

ssc
  • 35
  • 2
  • 9
  • This questions has been answered by @Albciff below. There were few changes that I made to the above code to get it to actually work. The updated code is below. – ssc Apr 06 '15 at 15:49

2 Answers2

0

I think there are two problems in your code, first you've to use appendChild method because you're trying to add a child inside your <ns2:OperationName> node (not appendNode method which not exist in your object), the second problem is that you're mixing the XmlSlurper classes with XmlBeans, due you can't add the "nodes" to an object from one engine to another.

You've to change the code inside your if statement to fit these corrections, so you can use something like:

if(reqRaveNumTwo != null && reqRaveNumTwo != "")
{
    /* create new node */   
    def nodeHolder  = groovyUtils.getXmlHolder("<ns3:RaveNum xmlns:ns3=\"...\">${reqRaveNumTwo}</ns3:RaveNum>")
    def itemNode = nodeHolder.getDomNode( "//ns3:RaveNum" )
    // import the node
    def secondRaveNumNode = parentNode.getOwnerDocument().importNode(itemNode,false)
    // and finally append it
    parentNode.appendChild(secondRaveNumNode)
}

instead of:

if(reqRaveNumTwo != null && reqRaveNumTwo != "")
{
    /* create new node */   
    def secondRaveNumNode = new XmlSlurper(false,false).parseText("""<ns3:RaveNum>${reqRaveNumTwo}</ns3:RaveNum>""")
    parentNode.appendNode(secondRaveNumNode)
}

This code using XmlBeans to create the new node looks less intuitive however this way it works :).

Additionally I saw this in your code: def groovyUtils = new ns4.eviware.soapui.support.GroovyUtils(context), I suppose it's only a typo however it must be def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)

Hope this helps,

albciff
  • 18,112
  • 4
  • 64
  • 89
0

Code was updated as below to get it to actually work:

/* Groovy Utilities Declaration */
def groovyUtils = new ns4.eviware.soapui.support.GroovyUtils(context)

/* Request Holder Setup */
def request      = context.expand('${RequestStepName#Request}')
def requestHolder    = groovyUtils.getXmlHolder("request")

/* Declaring Namespaces */
requestHolder.namespaces["soapenv"] = "http://schemas.xmlsoap.org/soap/envelope/"
requestHolder.namespaces["ns2"]     = "..."
requestHolder.namespaces["ns3"]     = "..."
requestHolder.namespaces["ns4"]     = "..."

/* Set few string names */
def operXString          = "//ns2:OperationName"
def raveNumXString       = "//ns3:RaveNum"

/* create object of Request nodes */
def parentNode = requestHolder.getDomNode(operXString)

def reqRaveNumTwo = "888"

if(reqRaveNumTwo != null && reqRaveNumTwo != "")
{
    /* create new node */   
    def nodeHolder  = groovyUtils.getXmlHolder("<ns3:RaveNum xmlns:ns3=\"ns3\">${reqRaveNumTwo}</ns3:RaveNum>")
    def itemNode = nodeHolder.getDomNode(raveNumXString)
    // import the node
    def secondRaveNumNode = parentNode.getOwnerDocument().importNode(itemNode,false)
    // and finally append it
    parentNode.appendChild(secondRaveNumNode)
}

/* Update the request holder properties */
requestHolder.updateProperty(true)
context.requestContent = requestHolder.xml
ssc
  • 35
  • 2
  • 9