Extract certain strings from JSON data strucure
SOLVED- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Extract certain strings from JSON data strucure
Hello community,
I have the following JSON formatted data:
{
"interfaces" : {
"interface" : [
{
"interface-name" : "eth0"
},
{
"interface-name" : "eth1"
},
{
"interface-name" : "cons0"
},
{
"interface-name" : "cons1"
}
]
}
}
I only want to have the strings"cons0" and "cons1" extracted/tansfered into e. g. an arrary for further usage in a SOAPUI test case. Does anyone has an idea?
Thanks in advance
Markus
Solved! Go to Solution.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @Markus_F
I may be misunderstanding from your description - but if that .json you supplied is a response and you just need to grab 2 node values from the .json response - you can use a property transfer with a properties step to allow you to use the values later on in your test.
i.e. so your step hierarchy in the test would be something like the following:
POST --> generates the .json response you mention Property Transfer (grabs the 2 attribute values you want to use later and populates the Properties step with these) Properties step (the values transferred to this step from the original POST via the Property Transfer step)
The way to do what you want is as follows:
Run your POST to generate the response.
Highlight the first attribute you want to transfer
Click on the 'Transfer To' dropdown to launch the menu
Select 'Add Properties step' (this will generate the property transfer step AND the Properties step)
Click ok to select the name of the target property
'Transfer to Property' form launches, click on ok to accept the defaults
For the second attribute you want to grab
Highlight the second attribute you want to transfer in the .json response
Click on the 'Transfer To' button to launch the menu
Select the relevant step that is the Properties test step created when the first attribute transfer was created
Select 'new' to create a new property to hold the json attribute value
Click ok to select the name of the target property
Transfer to Property form launches, click on ok to accept the defaults
At this point click on the Property Transfer step, click on each of the transfer and make sure both the Source and Target attributes are correctly populated - I've just run through this and I noticed that the second transfer's Target 'Property' field in the property transfer step is blank (might be a ReadyAPI! defect - as I keep doing this and it's always blank by default) - so I just set it to correct Property name (that is defined in the Properties step).
If you now run your test (ensuring the Property Transfer step is BEFORE the Properties step) - the values you want to save for subsequent usage will be saved within your Properties step.
Hope this helps!
rich
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Markus_F,
Can you please show more details on what you want?
If you just want to extract certain string from JSON data, it should be easy to process.
//
def slurper = new groovy.json.JsonSlurper().parseText(YourJsonData)
slurper.interfaces.interface.each{
// do something
}
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi rich,
thank you you for your input.
Forgot to say that the data is queried from a server with REST GET request.
The number of "interface-name" instances and the values in the REST response are varying. So, the easy way to just do a transfer from a fixed position into a property is not working.
I was thinking about parsing all "interface-name" instances in the REST response with a filter string to store only a certain subset of values for further use.
Any ideas how to do that in SOAPUI pro?
BR
Markus
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think you've a couple of choices here and I don't think my knowledge will do it as i think it'll probably be easier and more robust to rely on groovy (which is outside my skillset).
I've had similar issues before and how i handled this using the GUI was to add in additional parms to my GET query to retrieve a specific number or set of records. In my scenario i filtered my GET so that a specific number of recorda were returned nd passed these to a property step. I then used a datasource (GRID) type to build an array of records which sourced the values from the Properties step. My test needed 6 records (so i setup 6 instances of the repeated attribute values into properties) and i got this working but it failed if the GET request returned less than 6 records.....so my solution wasnt very robust, but it got the job done....but as i say, it wasnt pretty nor robust.
Perhaps one of the other lads can help out with a groovyscript option thats more robust than my approach? Or maybe there's a way of using the embedded functionality that I'm not aware of?
Cheers,
richie
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
aaronpliu gave you the main tactict. here is full groovy code to do what your original question asked...
.
.
.
import groovy.json.*;
def sampleJSONtxt = '''
{
"interfaces" : {
"interface" : [
{
"interface-name" : "eth0"
},
{
"interface-name" : "eth1"
},
{
"interface-name" : "cons0"
},
{
"interface-name" : "cons1"
}
]
}
}
''';
def interfaceNameList = [];
def sourceJSONobj = new JsonSlurper().parseText(sampleJSONtxt);
sourceJSONobj.interfaces.interface.each { interfaceName ->
log.info 'interfaceNameValue=' + interfaceName.'interface-name'.toString();
interfaceNameList.add(interfaceName.'interface-name'.toString());
};
interfaceNameList.each { name ->
log.info 'name of interface=' + name;
};
def filteredInterfaceNameList = [];
interfaceNameList.each { name ->
if (name.contains('cons')) {
filteredInterfaceNameList.add (name)
log.info 'name of filtered interface=' + name;
};
};
log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" done...';
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the code, it works fine
One more question:
Instead of having "cons0" and "cons1" in the log output window, how are they going into a property for further use?
Markus
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Markus,
I think your request was for an array that contained filtered values... The code above and replicated here was the key to that. The "filteredInterfaceNameList" is your resultant array (list type) that only contains the filtered values from the whole list.
The line above the log.info line is adding the filtered values to the empty list which you wanted to be able to do stuff with.
def filteredInterfaceNameList = [];
interfaceNameList.each { name ->
if (name.contains('cons')) {
filteredInterfaceNameList.add (name)
log.info 'name of filtered interface=' + name;
};
};
testRunner.testCase.testSteps["Properties"].setPropertyValue( "valueFromFilterA", filteredInterfaceNameList[0]);
testRunner.testCase.testSteps["Properties"].setPropertyValue( "valueFromFilterB", filteredInterfaceNameList[1]);
.
.
.
Adding a couple more lines to that shows how to populate a test step named "Properies" which you can insert from a "Add Step" or "Insert Step" on the Test case. With "Properties" content, you can use in other test steps in the test case.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Todd,
thanks but the number of instances of interface-name with "cons" in my json structure varies. "cons0" and "cons1" was just as an example. So I need a tip how to set properties dynamically.
Markus
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Markus,
Given that you have a list of values that can vary between 0 and infinity, you can set properties from it easily enough, but now you have to give the property a name for each of those values. For each value a unique name must be created unless you don't care about how many values are in a list. The following builds on prior examples in this thread:
filteredInterfaceNameList = [];
interfaceNameList.each { name ->
if (name.contains('cons')) {
filteredInterfaceNameList.add (name)
};
};
filteredInterfaceNameList.eachWithIndex { interfaceName, idx ->
propName = "somePropertyNameValue" + idx.toString();
propValue = interfaceName;
testRunner.testCase.testSteps["Properties"].setPropertyValue( propName, propValue);
};
.
.
.
You have never stated how you would use this dynamically, so I can only imagine... The above code allows you to dynamically write properties from 0 to infinity (or however many Smartbear will allow). 🙂
