I'm gonna include the xml structure below:
#Rao, #tim_yates. The actual xml is:
<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>encoded64 text</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>
I need to include a new Node in . The new XML must be:
<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>
<Salutation>text</Salutation>
</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>
The question is how to append a new node in ?
I've found many samples how to use appendNode, however, it is always a
root.child. I need to go further in my XML structure and append a node at
prnReq.ltrPrnReqs.ltrPrnReq.ltrData
the node to be included is <salutation>
Any comments are welcome.
Below the current code.
Many thanks!
import groovy.xml.QName
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
File doc = new File("C:/Temp/letter_.xml")
def prnReq = new XmlSlurper().parse(doc)
prnReq.ltrPrnReqs.ltrPrnReq.each {
def encodedString = it.ltrData.toString()
Base64.Decoder decoder = Base64.getMimeDecoder()
byte[] decodedByteArray = decoder.decode(encodedString)
def output = new String(decodedByteArray)
println output
output.splitEachLine(';') { items ->
println "raSalutation: " + items[0]
println "raFromAcc: " + items[1]
println "raPayableTo: " + items[2]
println "raSortCode: " + items[3]
println "raAccNum: " + items[4]
println "raReference: " + items[5]
println "raSendDate: " + items[6]
println "raRecDate: " + items[7]
println "raAmount: " + items[8]
println "raDummy1: " + items[9]
println "raFirstAmt: " + items[10]
println "raFirstDate: " + items[11]
println "raRegularAmt: " + items[12]
println "raRegularDate: " + items[13]
println "raFrequency: " + items[14]
println "raFee: " + items[15]
def toAdd = '"<salutation>$item[0]</salutation>"'
fragToAdd = new XmlSlurper().parseText(toAdd)
prnReq.ltrPrnReqs.ltrPrnReq.ltrData.appendNode(fragToAdd)
}
String outputFileName = "C:/Temp/letter_.xml"
XmlUtil xmlUtil = new XmlUtil()
xmlUtil.serialize(prnReq, new FileWriter(new File(outputFileName)))
}
You should be able to add the new node using appendNode.
Here is complete sample showing how to do it.
def xmlString = """<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>encoded64 text</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>"""
def xml = new XmlSlurper().parseText(xmlString)
def ltrData = xml.'**'.find{it.name() == 'ltrData'}
ltrData.replaceBody()
ltrData.appendNode {
Salutation('text')
}
println groovy.xml.XmlUtil.serialize(xml)
You can quickly try it online demo
Related
I would like to change only the numbers of a line.
Source file:
IMAGE_VERSION_TD_S=1.108.1.1
IMAGE_VERSION_CPO=1.87.13.1
IMAGE_VERSION_CVM=1.71.1.1
I would like to search for a string like ("IMAGE_VERSION_CPO=") and change only the numbers to 1.90.12.1.
Output file:
IMAGE_VERSION_TD_S=1.108.1.1
IMAGE_VERSION_CPO=1.90.12.1
IMAGE_VERSION_CVM=1.71.1.1
I have tried on this way but it generated a new line on the final file:
def data = readFile(file: pathEnv)
def lines = data.readLines()
def strNewEnv = ''
lines.each {
String line ->
if (line.startsWith("IMAGE_VERSION_CPO=")) {
strNewEnv = strNewEnv + '\n' + 'IMAGE_VERSION_CPO=' + imageVersion
} else {
strNewEnv = strNewEnv + '\n' + line
}
println line
}
println strNewEnv
writeFile file: directoryPortal+"/${params.ENVIROMENT}/"+envFile, text: strNewEnv
If this is a properties file, use the readProperties step:
def props = readProperties file: pathEnv, text: "IMAGE_VERSION_CPO=${imageVersion}"
writeFile file: "${directoryPortal}/${params.ENVIROMENT}/${envFile}", text: props.collect { "${it.key}=${it.value}" }.join("\n")
If, for some reason, this isn't a props file:
def data = readFile(file: pathEnv)
data = data.replaceAll(/(?<=IMAGE_VERSION_CPO=)[\d\.]+/, imageVersion)
writeFile file: "${directoryPortal}/${params.ENVIROMENT}/${envFile}", text: data
There's likely a much better regex for that but it seems to be working
I've recently started using XML Slurper and am trying to access a specific child node from a SOAP envelope. Below is an extract of the XML I'm working with:
<cons:ConsumerName>
<cons:FirstName>Robert</cons:FirstName>
<cons:MiddleName>John</cons:MiddleName>
<cons:FamilyName>Smith</cons:FamilyName>
</cons:ConsumerName>
<cons:ContactPersonName>
<cons:FirstName>William</cons:FirstName>
<cons:MiddleName>Michael</cons:MiddleName>
<cons:FamilyName>Doe</cons:FamilyName>
</cons:ContactPersonName>
I'm trying to access the value of FirstName in the ConusmerName block, I've only been able to get a list of both of the first name values by using:
def block = new XmlSlurper().parseText(text).'**'.findAll{it.name()=='FirstName'}
I tried to get the first name for the ConsumerName block only, by using:
def block = new XmlSlurper().parseText(text).'ConsumerName'.findAll{it.name()=='FirstName'}
But nothing gets returned by that, I can't work out what I'm doing wrong?
I fixed up your xml and providing an answer here:
def text = '<?xml version="1.0" encoding="UTF-8"?>' +
'<cons:Consumer xmlns:cons="urn:corp:cons">' +
' <cons:ConsumerName>' +
' <cons:FirstName>Robert</cons:FirstName>' +
' <cons:MiddleName>John</cons:MiddleName>' +
' <cons:FamilyName>Smith</cons:FamilyName>' +
' </cons:ConsumerName>' +
'' +
' <cons:ContactPersonName>' +
' <cons:FirstName>William</cons:FirstName>' +
' <cons:MiddleName>Michael</cons:MiddleName>' +
' <cons:FamilyName>Doe</cons:FamilyName>' +
' </cons:ContactPersonName>' +
'</cons:Consumer>'
def consumer = new XmlSlurper().parseText(text)
println "Consumer first name: ${consumer.ConsumerName.FirstName}"
Output:
Consumer first name: Robert
To get the firstName value in the ConsumerName block of XML, I used the following:
def text = new File(requestFilePath).text
def fieldValue = new XmlSlurper().parseText(text).'**'.findAll{it.name()==tagBlockName}.getAt(tagName)[0]
def var = (String)fieldValue
I have a requirement to write a results (Pass/Fail) in the same excel sheet where the script reads the parameter in a FOR loop. It is throwing an error:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'jxl.read.biff.WorkbookParser#3da0525b' with class 'jxl.read.biff.WorkbookParser' to class 'jxl.write.WritableWorkbook' error at line: 16
My code:
import jxl.*;
import jxl.write.*;
import java.io.*;
import groovy.json.JsonSlurper
//Get project path
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def projectPath = groovyUtils.projectPath
def testCaseName = testRunner.testCase.name
//Read excel file and get the input value
WritableWorkbook xlwb = Workbook.getWorkbook(new File ("${projectPath}\\${testCaseName}.xls"))
Sheet inputxlsh = xlwb.getSheet(0)
inputRowCount = inputxlsh.getRows();
WritableSheet outputxlsh = xlwb.getSheet(1)
outputRowCount = outputxlsh.getRows();
log.info "Executing Test Case " + testCaseName
log.info "Total records to send API request to webservice from the file : " + inputRowCount -1
for (i=0;i<inputRowCount-1;i++)
{
Cell requestParam1 = inputxlsh.getCell(0,i+1)
affkey = requestParam1.getContents()
Cell requestParam2 = inputxlsh.getCell(1,i+1)
etid = requestParam2.getContents()
def soapTestCase = context.testCase
//Set the request property value (Parameter)
requestPropertyVariable = soapTestCase.getTestStepByName("requestProperty")
requestPropertyVariable.setPropertyValue("affkey",affkey)
requestPropertyVariable.setPropertyValue("etid",etid)
log.info "Reading record " + (i+1) + " from input file"
log.info "Sending request with affkey " + affkey
log.info "Sending request with etid " + etid
//Post a request to webservice
def responseContent = testRunner.runTestStepByName("showetidRequest").getResponse()
def responseText = responseContent.getContentAsString()
//Save the output file
def fileObj = new File("${projectPath}\\API_Response\\${testRunner.testCase.name}\\${etid}_Response.txt")
saveToFile(fileObj, responseText)
//Get the response value
JsonSlurper jsonResponseContent = new JsonSlurper()
def jsonResponseObject = jsonResponseContent.parseText(responseText)
//Validate results
Cell headerParam1 = outputxlsh.getCell(0,0)
Cell headerParam2 = outputxlsh.getCell(1,0)
Cell headerParam3 = outputxlsh.getCell(2,0)
Cell headerParam4 = outputxlsh.getCell(3,0)
Cell headerParam5 = outputxlsh.getCell(4,0)
Cell headerParam6 = outputxlsh.getCell(5,0)
for (k = 0; k < outputRowCount-1; k++) {
Cell responseParam1 = outputxlsh.getCell(0,k+1)
Cell responseParam2 = outputxlsh.getCell(1,k+1)
Cell responseParam3 = outputxlsh.getCell(2,k+1)
Cell responseParam4 = outputxlsh.getCell(3,k+1)
Cell responseParam5 = outputxlsh.getCell(4,k+1)
Cell responseParam6 = outputxlsh.getCell(5,k+1)
expectedAffiliatesWithContent = responseParam1.getContents()
expectedEntityName = responseParam2.getContents()
expectedName = responseParam3.getContents()
expectedSaleMessageId = responseParam4.getContents()
expectedTitle = responseParam5.getContents()
expectedetid = responseParam6.getContents()
if(etid==expectedetid){
responseAffiliatesWithContent = jsonResponseObject.AffiliatesWithContent.getAt(0).getAt(0)
responseEntityName = jsonResponseObject.Genre.EntityName.getAt(0)
responseName = jsonResponseObject.Genre.Name.getAt(0)
responseSaleMessageId = jsonResponseObject.SaleMessage.Id.getAt(0)
responseTitle = jsonResponseObject.Title.getAt(0)
log.info responseAffiliatesWithContent
log.info responseEntityName
log.info responseName
log.info responseSaleMessageId
log.info responseTitle
if (responseAffiliatesWithContent==expectedAffiliatesWithContent&&responseEntityName==expectedEntityName&&responseName==expectedName&&responseSaleMessageId==expectedSaleMessageId&&
responseTitle==expectedTitle)
{
log.info "The data is matched for record " + (k +1) + " hence test case passed "
Label l = new Label(7, k +1, "Pass");
outputxlsh.addCell(l);
xlwb.write();
}
else {
log.info "The data is matched for record " + (k +1) + " hence test case failed "
}
}
}
}
//Clear Property
requestPropertyVariable.setPropertyValue("affkey","")
requestPropertyVariable.setPropertyValue("etid","")
//Write file method
def saveToFile(fileObj, content) {
if (!fileObj.parentFile.exists()) {
fileObj.parentFile.mkdirs()
}
fileObj.write(content)
log.info "Response for etid " + etid + " is stored in " + "${etid}_Response.txt"
assert fileObj.exists(), "${fileObj.name} not created"
}
If you want a write able copy call createWorkbook function
WritableWorkbook xlwb = Workbook.createWorkbook(new File ("${projectPath}\\${testCaseName}.xls"))
If you don't want write able copy save in Workbook object instead
Workbook workbook = Workbook.getWorkbook((new File ("${projectPath}\\${testCaseName}.xls"))
I have achieved the requirement based on below code
def inptDataWb = new HSSFWorkbook(xlwb);
def inputxlsh = inptDataWb.getSheetAt(2);
wrtResult = outputxlsh.getRow(k+1).getCell(3);
wrtResult.setCellValue("P");
wrtResult = outputxlsh.getRow(k+1).getCell(5);
wrtResult.setCellValue("");
inptDataWb.write(xlOwb);
I have a SOAP request which has dynamic values generated by random method. How to capture these generated values to log?
My SOAP request:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/">
<soap:Header/>
<soap:Body>
<web:ChangeLengthUnit>
<web:LengthValue>${=(int)(Math.random()*9999)}</web:LengthValue>
<web:fromLengthUnit>Inches</web:fromLengthUnit>
<web:toLengthUnit>Centimeters</web:toLengthUnit>
</web:ChangeLengthUnit>
</soap:Body>
</soap:Envelope>
Groovy script:
import com.eviware.soapui.support.GroovyUtils;
def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName("Project1")
tCase = prj.testSuites['TestSuite'].testCases['TestCase']
tStep = tCase.getTestStepByName("ChangeLengthUnit")
def stepReq = tStep.getProperty("Request").getValue()
def runner = tStep.run(testRunner, context)
log.info ("runner status ....... : " + runner.hasResponse())
log.info stepReq
for( assertion in tStep.assertionList )
{
log.info "Assertion [" + assertion.label + "] has status [" + assertion.status + "]"
for( e in assertion.errors )
log.info "-> Error [" + e.message + "]"
}
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( stepReq.toString() )
log.info holder.getNodeValues( "//web:LengthValue" ).toString()
Above groovy script is giving output as below:
Wed Oct 18 14:55:13 SGT 2017:INFO:[${=(int)(Math.random()*9999)}]
Actual value of LengthValue tag = 3490, How to get this value ?
It can easily read from RawRequest property using Script Assertion for the same request step.
assert context.rawRequest, 'Request is empty or null'
def xml = new XmlSlurper().parseText(context.rawRequest)
def actualValueInTheRequest = xml.'**'.find{it.name() == 'LengthValue'}?.text()
log.info "Value for LengthValue in the actual request is : $actualValueInTheRequest"
I think what you're doing is getting the LengthValue from the request 'template' not what SoapUI has actually passed to the web service.
In your example, you have...
def stepReq = tStep.getProperty("Request").getValue()
The request is what you see in SoapUI that includes your vars, e.g. ${myVar}. I think what you're after is the 'raw request'.
In SoapUI, run the request and after it has ran, you should see a tab labelled 'Raw Request'. This is what SoapUI actually sends to the web service, in here you'll see that the vars have been evaluated and will show the value, which is what you are after.
I've taken your example and made some mods it. I haven't tested it, but it should help you.
import com.eviware.soapui.support.GroovyUtils;
def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName("Project1")
tCase = prj.testSuites['TestSuite'].testCases['TestCase']
tStep = tCase.getTestStepByName("ChangeLengthUnit")
def stepReq = tStep.getProperty("Request").getValue()
def runner = tStep.run(testRunner, context)
// CHA MOD - Can only get raw request after running the step.
def rawRequest = context.expand( '${ChangeLengthUnit#RawRequest}' )
//CHA MOD - Quick look at the rawRequest...
log.info(rawRequest);
log.info ("runner status ....... : " + runner.hasResponse())
log.info stepReq
for( assertion in tStep.assertionList )
{
log.info "Assertion [" + assertion.label + "] has status [" + assertion.status + "]"
for( e in assertion.errors )
log.info "-> Error [" + e.message + "]"
}
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( stepReq.toString() )
log.info holder.getNodeValues( "//web:LengthValue" ).toString()
//CHA MOD - Get the length from the raw request...
holder = groovyUtils.getXmlHolder( rawRequest.toString() )
log.info holder.getNodeValues( "//web:LengthValue" ).toString()
You are getting value from the actual request. Try to get the data from RawRequest
use below code
def holder = groovyUtils.getXmlHolder(mentionThenameofthestep#RawRequest)
The above code will point to Raw request of your teststep which contains actual value passed during execution instead of "${=(int)(Math.random()*9999)}"
I have the following line in my code
def genList = (args[]?.size() >=4)?args[3]: "
when I run my whole code I get the following error
expecting anything but ''\n''; got it anyway at line: 9, column: 113
here I am adding the whole code so you can see what I am doing
def copyAndReplaceText(source, dest, targetText, replaceText){
dest.write(source.text.replaceAll(targetText, replaceText))
}
def dire = new File(args[0])
def genList = (args[]?.size() >=4)?args[3]: " // check here if argument 4 is provided, and generate output if so
def outputList = ""
dire.eachFile {
if (it.isFile()) {
println it.canonicalPath
// TODO 1: copy source file to *.bak file
copy = { File src,File dest->
def input = src.newDataInputStream()
def output = dest.newDataOutputStream()
output << input
input.close()
output.close()
}
//File srcFile = new File(args[0])
//File destFile = new File(args[1])
//File srcFile = new File('/geretd/resume.txt')
//File destFile = new File('/geretd/resumebak.txt')
File srcFile = it
File destFile = newFile(srcFile + '~')
copy(srcFile,destFile)
// search and replace to temporary file named xxxx~, old text with new text. TODO 2: modify copyAndReplaceText to take 4 parameters.
if( copyAndReplaceText(it, it+"~", args[1], args[2]) ) {
// TODO 3: remove old file (it)
it.delete()
// TODO 4: rename temporary file (it+"~") to (it)
// If file was modified and parameter 4 was provided, add modified file name (it) to list
if (genList != null) {
// add modified name to list
outputList += it + "\n\r"
}
}
}
}
// TODO 5: if outputList is not empty (""), generate to required file (args[3])
if (outputList != ""){
def outPut = new File(genList)
outPut.write(outputList)
}
Thank you
Just close your double quotes
def genList = (args?.size() >=4)?args[3]: ""
The specific OP question was already answered, but for those who came across similar error messages in Groovy, like:
expecting anything but '\n'; got it anyway
expecting '"', found '\n'
It could be caused due to multi-line GString ${content} in the script, which should be quoted with triple quotes (single or double):
''' ${content} ''' or """ ${content} """
Why do you have a single " at the end of this line: def genList = (args[]?.size() >=4)?args[3]: "?
You need to make it: def genList = (args[]?.size() >=4)?args[3]: ""
You need to add a ; token at the end of def outputList = ""
Also get rid of the " at the end of def genList = (args[]?.size() >=4)?args[3]: "