Groovy split results - groovy

Script:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;
import groovy.xml.StreamingMarkupBuilder;
import groovy.xml.*;
def Message processData(Message message) {
// get body
def body = message.getBody(java.io.Reader);
// parse xml body
def result = new XmlSlurper().parse(body);
def message1 = result.Message1;
def message2 = result.Message2;
def one = message1.EmployeeDataReplicationConfirmation.EmployeeDataReplicationConfirmation.collect { it.personId.text() }
def two = message2.queryCompoundEmployeeResponse.CompoundEmployee.collect { it.person.person_id.text() }
def intersect = one.intersect(two)
def userid1 = ((one - intersect) + (two - intersect))
println((one - intersect) + (two - intersect))
return message;
Output:
Console Output
Running...
[6107, 10140, 11774]
In the text 1 and text2 fields are different ids. This command will give me IDs that are the same in both.
But he gives them to me like this:[6107, 10140, 11774]
But i need it in XML.. like ..
I need this
<Person>
<User>
<userid>6107</userid>
</User>
<User>
<userid>10140</userid>
</User>
<User>
<userid>11774</userid>
</User>
how can i do it ? Thanks :)

You can use the MarkupBuilder class to create your XML, imagine you already have your data ready, then the only thing you need to do is:
import groovy.xml.MarkupBuilder
def userIds = [6107, 10140, 11774]
def xml = new StringWriter()
def builder = new MarkupBuilder(xml)
builder.people() {
userIds.each { id ->
user() {
userId(id)
}
}
}
println xml
This will be the output
<people>
<user>
<userId>6107</userId>
</user>
<user>
<userId>10140</userId>
</user>
<user>
<userId>11774</userId>
</user>
</people>
For more examples of working with XML, you can see my gist Working with xml

Related

Parsing xml file at build time and modify its values/content

I want to parse a xml file during build time in build.gradle file and want to modify some values of xml, i follow this SO question and answer Load, modify, and write an XML document in Groovy but not able to get any change in my xml file. can anyone help me out. Thanks
code in build.gradle :
def overrideLocalyticsValues(String token) {
def xmlFile = "/path_to_file_saved_in_values/file.xml"
def locXml = new XmlParser().parse(xmlFile)
locXml.resources[0].each {
it.#ll_app_key = "ll_app_key"
it.value = "123456"
}
XmlNodePrinter nodePrinter = new XmlNodePrinter(new PrintWriter(new FileWriter(xmlFile)))
nodePrinter.preserveWhitespace = true
nodePrinter.print(locXml)
}
xml file :
<resources>
<string name="ll_app_key" translatable="false">MY_APP_KEY</string>
<string name="ll_gcm_sender_id" translatable="false">MY_GCM_SENDER_ID</string>
</resources>
In your code : Is it right ...? Where is node name and attribute ..?
locXml.resources[0].each { // Wrongly entered without node name
it.#ll_app_key = "ll_app_key" // Attribute name #name
it.value = "123456" // you can't change or load values here
}
You tried to read and write a same file. Try this code which replaces the exact node of the xml file. XmlSlurper provides this facility.
Updated :
import groovy.util.XmlSlurper
import groovy.xml.XmlUtil
def xmlFile = "test.xml"
def locXml = new XmlSlurper().parse(xmlFile)
locXml.'**'.findAll{ if (it.name() == 'string' && it.#name == "ll_app_key") it.replaceBody 12345 }
new File (xmlFile).text = XmlUtil.serialize(locXml)
Groovy has a better method for this than basic replacement like you're trying to do - the SimpleTemplateEngine
static void main(String[] args) {
def templateEngine = new SimpleTemplateEngine()
def template = '<someXml>${someValue}</someXml>'
def templateArgs = [someValue: "Hello world!"]
println templateEngine.createTemplate(template).make(templateArgs).toString()
}
Output:
<someXml>Hello world!</someXml>

How to check if an xml element is displayed using a script assertion

I want to perform an assertion within SOAP UI to check if the 'BookingCode' is displayed but I am not sure how to do it. I am using .size() but it keeps failing whether there is or isn't any booking code:
Below is an xml example but I xxx out the information:
<soap:xxx">
<soap:Body>
<getBookingsResponse xmlns="http://xxx/">
<Bookings>
<Booking Id="xxx" BookingCode="xxx" >
Below is the script assertion itself:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def serviceResponse = context.expand( '${getBookings#Response}' )
def xml = new XmlSlurper().parseText( serviceResponse )
def BookingRef = xml.'soap:Body'.getBookingsResponse[0].Bookings[0].Booking.#BookingCode
assert BookingRef.size() != 0
Thank you
Here you go, comments in-line:
Script Assertion
//Pass the xml string to parseText method
def pxml = new XmlSlurper().parseText(context.response)
//Get the BookingCode attributes
def codes = pxml.'**'.findAll{ it.name() == 'Booking' }*.#BookingCode*.text()
log.info codes
assert codes.size !=0

Groovy XMLSlurper Parse Values

I am so close to getting my code completed. I would like to get only the values in an array. Right now I am getting XML declaration plus the line.
Here's my code:
import groovy.xml.XmlUtil
def serverList = new
XmlSlurper().parse("/app/jenkins/jobs/firstsos_servers.xml")
def output = []
serverList.Server.find { it.#name == SERVER}.CleanUp.GZIP.File.each{
output.add(XmlUtil.serialize(it))
}
return output
Here is my XML File:
<ServerList>
<Server name="testserver1">
<CleanUp>
<GZIP>
<File KeepDays="30">log1</File>
<File KeepDays="30">log1.2</File>
</GZIP>
</CleanUp>
</Server>
<Server name="testserver2">
<CleanUp>
<GZIP>
<File KeepDays="30">log2</File>
</GZIP>
</CleanUp>
</Server>
<Server name="testserver3">
<CleanUp>
<GZIP>
<File KeepDays="30">log3</File>
</GZIP>
</CleanUp>
</Server>
When I select testserver1 my output should be:
['log1','log1.2']
What I am getting is this:
<?xml version="1.0" encoding="UTF-8"?><File KeepDays="30">log1</File>
<?xml version="1.0" encoding="UTF-8"?><File KeepDays="30">log2</File>
You need not require to use XmlUtil.serialize()
Here is what you need and following inline comments.
//Define which server you need
def SERVER = 'testserver1'
//Pass the
def serverList = new
XmlSlurper().parse("/app/jenkins/jobs/firstsos_servers.xml")
//Get the filtered file names
def output = serverList.Server.findAll{it.#name == SERVER}.'**'.findAll{it.name() == 'File'}*.text()
println output
return output
Output:
You can quickly try online Demo
def output = []
def node = serverList.Server.find {
it.'name' = 'testserver1'
}.CleanUp.GZIP.File.each {
output.add(it)
}
return output
also there is a copy & paste error in your .xml. You have to add </ServerList> at the end.
`

how i use groovy to insert a node which has attribute and value

there is a simple xml, for example:
def rootNode = new XmlSlurper().parseText(
'<root>
<one a1="uno!"/>
<two>Some text!</two>
</root>' )
how can i insert a node
<three type='c'>2334</three>
into root?
i have use this way to insert
rootNode.appendNode{three(type:'c') 2334}
rootNode = new XmlSlurper().parseText(rootNode)
but it return exception.
Below script should give you desired result:
change from yours: three (type:'c', 2334)
import groovy.xml.*
def rootNode = new XmlSlurper().parseText('<root><one a1="uno!"/><two>Some text!</two></root>' )
rootNode.appendNode {
three (type:'c', 2334)
}
def newRootNode = new StreamingMarkupBuilder().bind {mkp.yield rootNode}.toString()
println newRootNode
Output:
<root><one a1='uno!'></one><two>Some text!</two><three type='c'>2334</three></root>

Why am I getting StackOverflowError?

In Groovy Console I have this:
import groovy.util.*
import org.codehaus.groovy.runtime.*
def gse = new GroovyScriptEngine("c:\\temp")
def script = gse.loadScriptByName("say.groovy")
this.metaClass.mixin script
say("bye")
say.groovy contains
def say(String msg) {
println(msg)
}
Edit: I filed a bug report: https://svn.dentaku.codehaus.org/browse/GROOVY-4214
It's when it hits the line:
this.metaClass.mixin script
The loaded script probably has a reference to the class that loaded it (this class), so when you try and mix it in, you get an endless loop.
A workaround is to do:
def gse = new groovy.util.GroovyScriptEngine( '/tmp' )
def script = gse.loadScriptByName( 'say.groovy' )
script.newInstance().with {
say("bye")
}
[edit]
It seems to work if you use your original script, but change say.groovy to
class Say {
def say( msg ) {
println msg
}
}

Resources