How to get all the XML nodes and its values from a XML with groovy? - groovy

I have an XML like below.
xml1 = '''
<?xml version="1.0" encoding="UTF-8"?>
<soap>
<group1>
<g1node1>g1value1</g1node1>
<g1node2>g1value2</g1node2>
<g1node3>g1value3</g1node3>
</group1>
<group2 attr="attrvalue1">
<g2node1>g2value1</g2node1>
<g2node2>g2value2</g2node2>
<g2node3>g2value3</g2node3>
</group2>
</soap>
'''
Here, i need to get all the xml node and its values as output, either as line by line result and as a list with groovy. The output should look like
g1node1 = g1value1
g1node2 = g1value2
... and so on...
or either with a groovy map like below
out = [g1node1 : "g1value1", g1node2 : "g1value2", ...and so on...]
can anyone help me how to achieve this with groovy code?

I would still like to know (as Tim mentioned) what you have tried yet, but here is my itch:
def result = new XmlSlurper().parseText( xml )
result.'**'.collectEntries { !it.childNodes() ? [ it.name(), it.text() ] : [:] }

Related

XML filtering based on value of a field using Groovy Script

I have below XML to filter based on the value of custom_string14 field under job_information segment, I have to filter the CompoundEmployee segments from xml based on the values present in an array [MW_9X, MW_9R]. If I find the value of custom_string14 not present in the array, i need to ignore that CompoundEmployee. As shown below job_information segment can occur multiple times
<?xml version="1.0" encoding="UTF-8"?>
<queryCompoundEmployeeResponse>
<CompoundEmployee>
<id>970</id>
<person>
<birth_name>Name1</birth_name>
<employment_information>
<job_information>
<custom_string13>MD_6_DAY</custom_string13>
<custom_string14>MW_9X</custom_string14>
</job_information>
<job_information>
<custom_string13>MD_6_DAY</custom_string13>
<custom_string14>MW_9S</custom_string14>
</job_information>
</employment_information>
</person>
</CompoundEmployee>
<CompoundEmployee>
<id>130</id>
<person>
<birth_name>Name2</birth_name>
<employment_information>
<job_information>
<custom_string13>MD_6_DAY</custom_string13>
<custom_string14>MW_9R</custom_string14>
</job_information>
<job_information>
<custom_string13>MD_6_DAY</custom_string13>
<custom_string14>MW_9R</custom_string14>
</job_information>
</employment_information>
</person>
</CompoundEmployee>
</queryCompoundEmployeeResponse>
I tried with below Groovy script and i am not able to capture all item in one node. Please help with below script as I am new to Groovy and stuck with this issue
import groovy.xml.*;
def body = """//Add Above XML here//"""
def array = ["MW_9X", "MW_9R"]
def list = new XmlParser().parseText(body)
def flag = true
def filtered = []
for(item in list)
{
def companyRules = item.'**'.custom_string14.toArray()
for(ech in companyRules)
{
println ech.text()
if(!array.contains(ech.text()))
{
flag = false
}
}
if(flag)
{
filtered = filtered + item
}
else
{
flag = true
}
}
filtered = filtered.toString()
def selected = XmlUtil.serialize(filtered)
println selected

How to extract value from a string in XML response using karate

Unfortunately the respons ei am getting from my backend is not in correct xml format and it's giving the response in a bad format like this:
<soapenv:Body>
<ns2:getInputResponse xmlns:ns2="http://docs.oasisopen.org/ns/bpel4people/ws-humantask/api/200803">
<ns2:taskData xmlns:s186="http://www.w3.org/2001/XMLSchema-instance" xmlns:s187="http://www.w3.org/2001/XMLSchema" s186:type="s187:string"><?xml version="1.0" encoding="UTF-8"?>
<SubscriptionApprovalData xmlns="http://workflow.subscription.apimgt.carbon.wso2.org" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<apiName>Auto_Approval</apiName>
<apiVersion>v1</apiVersion>
<apiContext>/test/lambda/v1</apiContext>
<apiProvider>admin</apiProvider>
<subscriber>regtest</subscriber>
<applicationName>newApp</applicationName>
<tierName>Gold</tierName>
<workflowExternalRef>23d30bd8-51e3-4afe-aae0-3fa159d85a6b</workflowExternalRef>
<callBackURL>https://apistore-dev-dev-a878-14-ams10-nonp.qcpaws.qantas.com.au/services/WorkflowCallbackService</callBackURL>
</SubscriptionApprovalData></ns2:taskData>
</ns2:getInputResponse>
</soapenv:Body>
Now because of this Karate is not able to read the response and fetch the value of "workflowExternalRef" which is my goal for this test.
Is there any way karate can read it?
This is really messed up XML so please check with someone in your team if this can be fixed.
Anyway, since you can use Java in Karate, here is one way to do this. This is not production-quality code, please adapt as appropriate:
* string response = response
* def start = response.indexOf('workflowExternalRef>')
* def ref = response.substring(start + 23)
* def end = ref.indexOf('<')
* def ref = ref.substring(0, end)
* match ref == '23d30bd8-51e3-4afe-aae0-3fa159d85a6b'

Get XML child nodes and concatanate values with ; in Groovy

I have bellow XML document:
xmlIn:
<SalesOrder>
<Parameter>Parameter1</Parametro>
<Method>Method1</Metodo>
<Orders>
<Order>
<Salesman>44</Salesman>
<Customer>12345</Customer>
<OrderNumber>100200300</OrderNumber>
</Order>
<Order>
<Salesman>45</Salesman>
<Customer>67890</Customer>
<OrderNumber>400500600</OrderNumber>
</Order>
</Orders>
And I have a request to transform into a string in Groovy:
Field1;Field2;Field3
44;12345;100200300
45;67890;400500600
My source code is:
def parser = new XmlSlurper().parseText(xmlIn)
String header = 'Field1;Field2;Field3'
def lines = parser.Orders.Order.children().each {
it.text()
}.join(";")
prinln(header + "\n" + lines)
However this is producing:
Field1;Field2;Field3
44;12345;100200300;45;67890;400500600
Does anyone can help me on this?
Thank you very much!
def lines = parser.Orders.Order.collect{order->
order.children().collect{it.text()}.join(';')
}.join('\n')

Get values from properties file using Groovy

How to get values from properties file using Groovy?
I require to have a property file (.properties) which would have file names as key, and their destination path as the value. I will need the key to be resolved at runtime, depending on file that needs to be moved.
So far I am able to load the properties it seems but can't "get" the value from the loaded properties.
I referred to the thread : groovy: How to access to properties file? and following is the code snippet i have so far
def props = new Properties();
File propFile =
new File('D:/XX/XX_Batch/XX_BATCH_COMMON/src/main/resources/patchFiles.properties')
props.load(propFile.newDataInputStream())
def config = new ConfigSlurper().parse(props)
def ant = new AntBuilder()
def list = ant.fileScanner {
fileset(dir:getSrcPath()) {
include(name:"**/*")
}
}
for (f in list) {
def key = f.name
println(props)
println(config[key])
println(config)
def destn = new File(config['a'])
}
the properties file has the following entries for now :
jan-feb-mar.jsp=/XX/Test/1
XX-1.0.0-SNAPSHOT.jar=/XX/Test/1
a=b
c=d
Correct values are returned if I look up using either props.getProperty('a')
or,
config['a']
Also tried the code: notation
But as soon as switch to using the variable "key", as in config[key] it returns --> [:]
I am new to groovy, can't say what am i missing here.
It looks to me you complicate things too much.
Here's a simple example that should do the job:
For given test.properties file:
a=1
b=2
This code runs fine:
Properties properties = new Properties()
File propertiesFile = new File('test.properties')
propertiesFile.withInputStream {
properties.load(it)
}
def runtimeString = 'a'
assert properties."$runtimeString" == '1'
assert properties.b == '2'
Unless File is necessary, and if the file to be loaded is in src/main/resources or src/test/resources folder or in classpath, getResource() is another way to solve it.
eg.
def properties = new Properties()
//both leading / and no / is fine
this.getClass().getResource( '/application.properties' ).withInputStream {
properties.load(it)
}
//then: "access the properties"
properties."my.key"
Had a similar problem, we solved it with:
def content = readFile 'gradle.properties'
Properties properties = new Properties()
InputStream is = new ByteArrayInputStream(content.getBytes());
properties.load(is)
def runtimeString = 'SERVICE_VERSION_MINOR'
echo properties."$runtimeString"
SERVICE_VERSION_MINOR = properties."$runtimeString"
echo SERVICE_VERSION_MINOR
Just in case...
If a property key contains dot (.) then remember to put the key in quotes.
properties file:
a.x = 1
groovy:
Properties properties ...
println properties."a.x"
Properties properties = new Properties()
properties.load(new File("path/to/file.properties").newReader())
Just another way of doing it. Use this if it works for you. :)
Properties properties = new Properties()
//loading property file
File propertiesFile = new File(this.class.getResource('application.properties').getPath())
propertiesFile.withInputStream {
properties.load(it)
}
//Accessing the value from property file
properties.getProperty('userName')
With static method extension:
Properties.metaClass.static.fromFile =
{file -> new Properties().with{new File(file).withInputStream it.&load;it}}
def properties = Properties.fromFile('test.properties')
Groovy for getting value of property from "local.properties" by giving key.
Example- For finding value of this property's key is "mail.smtp.server"
In V5
ctx.getBean("configurationService")
configurationService = ctx.getBean("configurationService")
String value = configurationService.getConfiguration().getString("mail.smtp.server","")
In 1905
spring.getBean("configurationService")
configurationService = spring.getBean("configurationService")
String value = configurationService.getConfiguration().getString("mail.smtp.server","")

Groovy: Using Closure to create and return Map Elements

I am importing an XML and then creating a list of objects based on the information from the XML.
This is a sample of my XML:
<DCUniverse>
<SuperHeroes>
<SuperHero>
<SuperHeroName>SuperMan</SuperHeroName>
<SuperHeroDesc>Surviver of Krypton; Son of Jor-el</SuperHeroDesc>
<SuperHeroCode>SM</SuperHeroCode>
<SuperHeroAttrs>
<SuperHeroAttr Name="Strength">All</SuperHeroAttr>
<SuperHeroAttr Name="Weakness">Kryptonite</SuperHeroAttr>
<SuperHeroAttr Name="AlterEgo">Clark Kent</SuperHeroAttr>
</SuperHeroAttrs>
</SuperHero>
<SuperHero>
<SuperHeroName>Batman</SuperHeroName>
<SuperHeroDesc>The Dark Knight of Gothom City</SuperHeroDesc>
<SuperHeroCode>BM</SuperHeroCode>
<SuperHeroAttrs>
<SuperHeroAttr Name="Strength">Intellect</SuperHeroAttr>
<SuperHeroAttr Name="Weakness">Bullets</SuperHeroAttr>
<SuperHeroAttr Name="AlterEgo">Bruce Wayne</SuperHeroAttr>
</SuperHeroAttrs>
</SuperHero>
</SuperHeroes>
<DCUniverse>
Here is an example of the groovy script that I am running to create the objects:
class Hero{
def SuperHeroName
def SuperHeroDesc
def SuperHeroCode
def SuperHeroAttrLst = [:]
Hero(String name, String desc, String code, attrLst){
this.SuperHeroName=name
this.SuperHeroDesc=desc
this.SuperHeroCode=code
this.SuperHeroAttrLst.putAll(attrLst)
}
}
def heroList = []
def heroDoc = new XmlParser().parse('dossier.xml')
heroDoc.SuperHeroes.each{ faction ->
faction.SuperHero.each{ hero ->
heroList += new Hero( hero.SuperHeroName.text(),
hero.SuperHeroDesc.text(),
hero.SuperHeroCode.text(),
hero.SuperHeroAttrs.SuperHeroAttr.each{ attr ->
return [ (attr.'#Name') : (attr.text()) ]
})
}
}
When I run the above code, I get the following error:
java.lang.ClassCastException: groovy.util.Node cannot be cast to java.util.Map$Entry
I have a strong feeling that it has something to do with the last variable that the closure is trying to send to Hero Class Constructor. Commenting out
this.SuperHeroAttrLst.putAll(attrLst)
in the Hero Constructor allows the script to at least parse correctly. What I am trying to do is create a class based on the XML and place it in the list like:
heroList += new Hero('Batman',
'The Dark Knight of Gothom City',
'BM',
['Strength':'Intellect', 'Weakness':'Bullets', 'AlterEgo':'Bruce Wayne'] )
However, my variable typing is incorrect and I dont know enough about Groovy's (or Java's) syntax to make it work.
Any help that can be provided would be much appreciated. Thank you for your time.
I think you should change hero.SuperHeroAttrs.SuperHeroAttr.each{ //blah blah to:
hero.SuperHeroAttrs.inject([:]) { attributes, attr ->
attributes[attr.'#Name'] = attr.text()
return attributes
}

Resources