cancel
Showing results for 
Search instead for 
Did you mean: 

How do i find an xml node and insert one or more nodes right below that node?

SOLVED
Contributor

How do i find an xml node and insert one or more nodes right below that node?

Here is a sample xml:

<HomeOwnersContext xmlns="http://schemas.datacontract.org/2004/07/Homesite.Homeowners.ContextModel.Api.Context" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <DisplayOnlyData/>
<QuoteData>
<animalsBitten>false</animalsBitten>
<burglarAlarm>No</burglarAlarm>
<businessOnPremises>false</businessOnPremises>
<totalNumberOfPeople>2</totalNumberOfPeople>
</QuoteData>
<QuoteHeader>
<Channel>Direct_Web</Channel>
<FormCode>3</FormCode>
</QuoteHeader>
</HomeOwnersContext>

 

Now i want to find <burglarAlarm> node and insert the below node

<cancelledForNonPay>1</cancelledForNonPay> right below that node.

2 ACCEPTED SOLUTIONS

Accepted Solutions
Community Hero

Re: How do i find an xml node and insert one or more nodes right below that node?

Here's a quick groovy script that kind of does what

// get the request and its content content of the test
// Adjust "TEST STEP NAME" accordingly

def testRequest = context.testCase.testSteps["TEST STEP NAME"].testRequest
def request = testRequest.requestContent;

// log.info(request);

// create an array of lines of the request, split by newline characters
def splitRequest = request.split("\n");

// build a new, empty request
def newRequest = "";

// loop through every line in the request that was split
for (splitString in splitRequest)
{
	// if we find the line that needs replacing
	if (splitString.contains("<burglarAlarm>No</burglarAlarm>"))
	{
		// find the spacing tabs of the element in question
		def spacing = splitString.tokenize("<")[0];
		// create a new line that exists of the elemnet searched for, a new line character, and appropriate spacing.
		def newSplit = splitString + '\n' + spacing + "<cancelledForNonPay>1</cancelledForNonPay>" + "\n";
		newRequest += newSplit;
	}
	else
	{
		// if the line is not the one being searched for, append the line as normal, with new line.
		newRequest += splitString + '\n';
	}
}

log.info(newRequest);


// The line below, when uncommented, will overwrite the contents of test step "TEST STEP NAME"
//testRequest.setRequestContent(newRequest);

you want. 




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
Community Hero

Re: How do i find an xml node and insert one or more nodes right below that node?

I believe you want to replace my line here:

 

 

def request = testRequest.requestContent;

 

With:

 

def request = serialXML;

My scriprt assumed you were using XML from a pre-existing test step. Since that is not the case, you can set it to the value you are parsing from the Excel data source. That should work for what you want.




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
14 REPLIES 14
Super Contributor

Re: How do i find an xml node and insert one or more nodes right below that node?

https://community.smartbear.com/t5/SoapUI-Open-Source/How-do-i-prepare-requests-with-repeated-blocks...

This thread has the answer

Look at tips and tricks for groovy scripting on smartbear.com

You should be able to do this

 

Community Hero

Re: How do i find an xml node and insert one or more nodes right below that node?

Here's a quick groovy script that kind of does what

// get the request and its content content of the test
// Adjust "TEST STEP NAME" accordingly

def testRequest = context.testCase.testSteps["TEST STEP NAME"].testRequest
def request = testRequest.requestContent;

// log.info(request);

// create an array of lines of the request, split by newline characters
def splitRequest = request.split("\n");

// build a new, empty request
def newRequest = "";

// loop through every line in the request that was split
for (splitString in splitRequest)
{
	// if we find the line that needs replacing
	if (splitString.contains("<burglarAlarm>No</burglarAlarm>"))
	{
		// find the spacing tabs of the element in question
		def spacing = splitString.tokenize("<")[0];
		// create a new line that exists of the elemnet searched for, a new line character, and appropriate spacing.
		def newSplit = splitString + '\n' + spacing + "<cancelledForNonPay>1</cancelledForNonPay>" + "\n";
		newRequest += newSplit;
	}
	else
	{
		// if the line is not the one being searched for, append the line as normal, with new line.
		newRequest += splitString + '\n';
	}
}

log.info(newRequest);


// The line below, when uncommented, will overwrite the contents of test step "TEST STEP NAME"
//testRequest.setRequestContent(newRequest);

you want. 




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
Contributor

Re: How do i find an xml node and insert one or more nodes right below that node?

Thanks Sanj! 

But i couldn't find any methods to find or insert a node

Contributor

Re: How do i find an xml node and insert one or more nodes right below that node?

Hi msiadak,

 

Thanks for the solution. It worked! 

I am starting to learn groovy now with Ready API!

 

I got another question:

I was getting an xml from the excel sheet,serializing it and putting it into the REST request to get the response but now i am adding another step:

1> Getting xml from excel sheet(data source)

2> Serializing it

3> Find a node and insert a desired node right below it.

4> Put the new xml request in the REST request to get the response.

 

// Getting the xml and serializing it

def stateDetailsXML = context.expand( '${DataSource#StateDetailsXML}' )
def doc = new XmlParser().parseText(stateDetailsXML)
def serialXML = groovy.xml.XmlUtil.serialize(doc)

 

// Your piece of code to find and insert

def testRequest = context.testCase.testSteps["serialXML "].testRequest
def request = testRequest.requestContent;

// log.info(request);

// create an array of lines of the request, split by newline characters
def splitRequest = request.split("\n");

 

How do i modify the first 2 lines of your code to pass the serialized xml (serialXML) to your piece of code?

 

 

Community Hero

Re: How do i find an xml node and insert one or more nodes right below that node?

I believe you want to replace my line here:

 

 

def request = testRequest.requestContent;

 

With:

 

def request = serialXML;

My scriprt assumed you were using XML from a pre-existing test step. Since that is not the case, you can set it to the value you are parsing from the Excel data source. That should work for what you want.




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
Contributor

Re: How do i find an xml node and insert one or more nodes right below that node?

Got it thanks!

Community Hero

Re: How do i find an xml node and insert one or more nodes right below that node?

@Santhosh_P,

 

Here is the simple, better, readable and more groovified way of doing it. 

 

This way, you will not land into trouble if the xml has namespace prefixes.

 

 

//Pass xml string to parseText method and also declare the namespaces used in the xml
def pxml = new XmlSlurper().parseText(xml).declareNamespace('con':'http://schemas.datacontract.org/2004/07/Homesite.Homeowners.ContextModel.Api.Context', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance')
//Add the element after burglarAlarm
pxml.QuoteData.burglarAlarm + { con.cancelledForNonPay (1) } def output = groovy.xml.XmlUtil.serialize(pxml) log.info "Changed xml : \n $output"

 

The above script is also available (along with xml) here in my github

 



Regards,
Rao.
Community Hero

Re: How do i find an xml node and insert one or more nodes right below that node?

@msiadak, this is crude way of doing and doe sn't handle namespaces.


Regards,
Rao.
Community Hero

Re: How do i find an xml node and insert one or more nodes right below that node?

@nmrao: The example didn't have namespaces, so I didn't worry about them. The solution was crude, because I'm not doing this as a job, but to help people. I'm not going to sit down and architect the perfect groovy script, sorry. Calling something someone provided to try to help "crude" is kind of hurtful. Man Surprised




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
New Here?
Join us and watch the welcome video:
Top Kudoed Authors