How to rename a key in JSON - json

Here is my xml
<?xml version="1.0" encoding="utf-8"?>
<p:Order xmlns:p="http://no.lyse.ikt.altisalg.Order" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="filename.xsd" source="AltiSalg 2.4.4-IB-154-IB-154 (154)"><p:Customer><p:OrderId></p:OrderId>
<p:FirstName></p:FirstName>
<p:LastName></p:LastName>
<p:EmailAddress></p:EmailAddress>
<p:BirthDate></p:BirthDate>
<p:CellularPhone></p:CellularPhone>
<p:City></p:City>
<p:Country></p:Country>
<p:PostalCode></p:PostalCode>
<p:StreetAddress></p:StreetAddress>
<p:PartnerId></p:PartnerId>
<p:CommunicationPreferences><p:Phone></p:Phone>
<p:Email></p:Email>
<p:Mail></p:Mail>
<p:SMS></p:SMS>
</p:CommunicationPreferences>
<p:ServiceAgreement><p:AgreementType></p:AgreementType>
<p:AgreementStartDate></p:AgreementStartDate>
<p:AgreementStatus></p:AgreementStatus>
<p:Comment></p:Comment>
<p:ListOfAssets><p:Asset><p:ProductPartNumber></p:ProductPartNumber>
<p:Comments></p:Comments>
</p:Asset>
<p:Asset><p:ProductPartNumber></p:ProductPartNumber>
<p:Comments></p:Comments>
</p:Asset>
<p:Asset><p:ProductPartNumber></p:ProductPartNumber>
<p:Comments></p:Comments>
</p:Asset>
<p:Asset><p:ProductPartNumber></p:ProductPartNumber>
<p:Comments></p:Comments>
</p:Asset>
<p:Asset><p:ProductPartNumber></p:ProductPartNumber>
<p:Comments></p:Comments>
</p:Asset>
<p:Asset><p:ProductPartNumber></p:ProductPartNumber>
<p:Comments></p:Comments>
</p:Asset>
</p:ListOfAssets>
</p:ServiceAgreement>
</p:Customer>
</p:Order>
When i am trying to convert into xmltojson i got below screen shot keys.
i need to remove p: from all keys. i am unable to access key because of p: is coming. When i am trying to check online converting its working and its not remove from my code. i am working on node and using "xml-to-json-promise" Module
https://prnt.sc/hvzrzf
Note : I can not any change in XML file.

xml-to-json-promise is based on the xml2js package (which itself is based on sax-js). I use xml2js and promisify it myself, but the trick is the options.tagNameProcessors. Read about them in the docs
Use it like this:
const prefixMatch = new RegExp(/(?!xmlns)^.*:/)
function stripPrefix(str) {
return str.replace(prefixMatch, '');
}
convert.xmlDataToJSON(xml, {
tagNameProcessors: [stripPrefix]
// other options too
})
This is included in xml2js package and could be required like so:
const {stripPrefix} = require('xml2js/lib/processors')
Anyway, there ya go! Tag names are processed to rename the key (removing any prior prefix).

Related

XPath/JSONPath search of arrays

Our REST API is returning an array of nested objects. Using XPath or JSONPath, I would like to extract the id elements of each top level array object but not the children's id elements.
[
{
"id":"1",
"child":{
"id":"a"
}
},
{
"id":"2",
"child":{
"id":"b"
}
}
]
The expected output is 1, 2 and NOT 1, a, 2, b.
Can anybody help with the query syntax? I have the example at http://jsfiddle.net/dqvrfvc1/2/
Try selecting the id at a specific level:
search = JSON.search(data, '/*/*/id')
See the update here: http://jsfiddle.net/dqvrfvc1/5/
If we dump the XML to the console (console.log(JSON.toXML(data));) we see:
<d:data xmlns:d="defiant-namespace" d:constr="Array" d:mi="9">
<d:item d:mi="4">
<id d:constr="String" d:mi="1">1</id>
<child d:mi="3">
<id d:constr="String" d:mi="2">a</id>
</child>
</d:item>
<d:item d:mi="8">
<id d:constr="String" d:mi="5">2</id>
<child d:mi="7">
<id d:constr="String" d:mi="6">b</id>
</child>
</d:item>
</d:data>
This means that instead of /*/*/id, we can be even more specific with:
search = JSON.search(data, '/d:data/d:item/id')
Note: Namespace selection isn't possible, so there doesn't seem to be the need to bind the d: namespace prefix to the defiant-namespace uri.
Also, take a look at the "XPATH EVALUATOR" section of http://defiantjs.com and switch between XML and JSON views to see how the JSON is represented in XML. This will help you understand the the data structure and at what level id would be found.
Given you have jmeter in your tags here is a solution for it:
JSON Path Expression should look like: $[*].id
Demo:
References:
JSON Extractor
JSON Path: Getting Started
API Testing With JMeter and the JSON Extractor
You mentioned XPath: in XPath 3.1 this is
parse-json($data)?*?id

How do I extract a variable from XML using Postman?

I'm trying to extract a SessionId from the XML which is returned from a SOAP API.
I've read through the Postman documentation (several times over) but it wasn't the most helpful in achieving my goal.
What was suggested in a few blogs was to convert the XML to JSON, and then pick out the token and it's value from there, but that didn't help either.
I used the following in my Test:
var jsonObject = xml2Json(responseBody);
postman.setGlobalVariable("Session_Id", jsonObject.SessionID);
The above created the variable "Session_Id" but didn't actually assign a value to it. I'm stumped.
I'm definitely retrieving the data from the API, and it's viewable in Postman's "Body" Response.
To extract a variable from XML using Postman, first convert your XML to JSON, using the xml2Json converter method:
var responseJson = xml2Json(responseBody);
(Where "responseBody" is your xml body.)
Then use the console.log method to output your JSON data, as such:
console.log(responseJson);
Be sure to have followed this tutorial on Enabling Chrome Dev Tools in Postman
Inside your Test Runner, run the test, then right click and "Inspect" anywhere in the Runner. Select the "Console" tab once Chrome's Dev Tools launch. Expand the "Object" part.
Then drill-down (expand) until you see the Property whose data you need.
Thereafter, set the variable by appending each drill-down level to the parameter you want:
postman.setGlobalVariable("Session_Id", responseJson.UserSessionToken.SessionID);
In this case, "responseJson" is the object, "UserSessionToken" was the next level in the drill-down, and SessionId was the parameter I needed within that.
Note: This answer was the correct solution before v7.15.0 of postman. For versions later than this, the accepted answer may not work.
Since Postman v7.15.0 the accepted answer did not work for me (it used to before the update). You have to put the path segments into square brackets.
For example, in the following XML response:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<QuotesPrivateResponse>
<lease-service>
<duration-in-months>24</duration-in-months>
</lease-service>
</QuotesPrivateResponse>
to retrieve the value duration-in-months:
var response = xml2Json(responseBody);
var duration = response["QuotesPrivateResponse"]["lease-service"]["duration-in-months"];
pm.environment.set("duration", duration);
My strong suspicion is that this behaviour is caused when any of the element names contain hyphens.
Postman v7.20.1
I'd like to add my answer since above there are a couple of details that took me a while to solve:
how to cope with a multipart SOAP response
how to manage a JSON object
responseBody definition
Here's the first lines of my XML response to analyze:
------=_Part_694527_1470506002.1584708814081
Content-Type: application/xop+xml;charset=UTF-8;type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID:
<e3bd82ac-d88f-49d4-8088-e07ff1c8d407>
<?xml version="1.0" encoding="UTF-8" ?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<ns2:GenericResponse xmlns:ns2="http://XXXXXXXX">
<ns2:Service IdcService="XXXXXXXX">
<ns2:Document>
<ns2:Field name="XXXXXXXX:isSetDefault">1</ns2:Field>
<ns2:Field name="XXXXXXXX">CHECKIN_UNIVERSAL</ns2:Field>
After I noticed it was a multipart I've ended up with this Postman Test:
var response = pm.response.text();
var responseBody = response.substr(response.indexOf('<env:'));
pm.test("The body of the response is a valid XML", function () {
pm.expect(xml2Json(responseBody)).to.exist;
});
pm.test("UCM file upload checkin succesfull", function(){
var responseJson = xml2Json(responseBody);
var JsonFields = (responseJson['env:Envelope']['env:Body']['ns2:GenericResponse']['ns2:Service']['ns2:Document']['ns2:Field']);
JsonFields.forEach( field => {
if (field.name == 'StatusMessage'){
console.log("Field = " + field.name);
pm.expect(field.text().to.include("Successfully checked in"));
}
});
});

How can I find only base nodes of an XML file

I have an xml file with various nodes and want to get first nodes of it, not children. Here's my code:
function processXML(event:Event):void {
menu_xml = new XML(event.target.data);
trace (menu_xml.child("mainmenu"));
}
This code doesn't display anything. I'm using Flash Professional CC 2015.0.
EDIT: Here's the xml content:
<?xml version="1.0"?>
<mainmenu>
<home/>
<portfolio/>
<contact/>
<friends>
<joe/>
<karen/>
<bob/>
</friends>
</mainmenu>
EDIT 2: I need to get only these strings: home, portfolio, contact, friends.
Your variable menu_xml is the base node, by calling menu_xml.child("mainmenu") you are seeking for XML like this:
<mainmenu>//menu_xml
<mainmenu/>//menu_xml.child("mainmenu");
</mainmenu>
Obviously this doesn't exist and the function returns an empty XML record. Your data set:
<mainmenu>//menu_xml = new XML(event.target.data);
<home/>//menu_xml.child("home");
<portfolio/> //menu_xml.child("portfolio");
<contact/> //menu_xml.child("contact");
<friends>//menu_xml.child("friends");
<joe/> //menu_xml.child("friends").child("joe");
<karen/> //menu_xml.child("friends").child("karen");
<bob/> //menu_xml.child("friends").child("bob");
</friends>
</mainmenu>
EDIT: To get the node names you will have to loop through the XML object structure, by looping through the result of the children() you will be able to use the name() function to get the name of each child of the root
for each (var node:XML in menu_xml.children())
{
trace(node.name());
}
output:
home
portfolio
contact
friends
For more information about Traversing XML structures in AS3, I recommend the AS3 Documentation
trace("Data loaded."+menu_xml );

Perl module not getting correct web service output

Can someone validate this snippet and point out what I might be doing wrong?
This is my code which creates and does a SOAP call.
my $soap = SOAP::Lite->new()->proxy($proxy)->ns('http://example.com', 'ser')->getInfo(
SOAP::Data->name(chronicId => $ticket_num)->prefix('ser'),
SOAP::Data->name(sourceSystem => $sourceSystem)->prefix('ser'),
SOAP::Data->name(outputFormat => $outputFormat)->prefix('ser'),
SOAP::Data->name(uid => $uid)->prefix('ser'),
SOAP::Data->name(username => $username)->prefix('ser'),
SOAP::Data->name(guid => $guid)->prefix('ser')
);
$results = $soap->call($method);
This is the result I get, when I use a test script to execute the above code.
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getChronicInfoResponse xmlns:ns="http://example.com">
<ns:return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
{
"UID":"abc1234",
"GUID":"",
"CHRONICID":123,
"OUTPUTFORMAT":"json",
"USERNAME":"xyz",
"STATUS_SUB_CODE_NAME":"Active",
"SOURCESYSTEM":"abc",
"STATUS_NAME":"Open"
}
</ns:return>
</ns:getChronicInfoResponse>
</soapenv:Body>
</soapenv:Envelope>
However when I try to read the web server response into a variable and print it out, all I get is a 1 (it's not empty though) nothing else. The output is supposed to be in JSON, as shown above, which I would then need to parse.
Any guesses what I might be doing wrong? I am new to Perl so it could be a silly thing.
Sorry I missed the updates. I could use the dumper to see a proper response here, seems like I was receiving a hex value while doing a print on the results which was not right.
The dumper returns a JSON string like -
{
'return' => '{"ATTUID":"pm304a","GUID":"d353f542-43f6-421b-9573-4c9c39ce77e3","CHRONICID":420,"OUTPUTFORMAT":"json","USERNAME":"m91619","STATUS_SUB_CODE_NAME":"Active","SOURCESYSTEM":"Oasis","STATUS_NAME":"Open"}'
};
Now I am trying to parse this json using JSON:XS - decode_json, but end up in an error which says
Malformed JSON string neither array, object, number, string or atom,......
I think thats because of the 'return' in the string, maybe I can strip it out and then pass to decode?

parse json with ant

I have an ant build script that needs to pull files down from a web server. I can use the "get" task to pull these files down one by one. However, I'd like to be able to get a list of these files first and then iterate over the list with "get" to download the files. The webserver will report the list of files in json format, but I'm not sure how to parse json with ant.
Are there any ant plugins that allow for json parsing?
I used Dave's suggestion above and it worked out pretty well. Here's what I came up with:
(Note, I ripped this out of my actual build file and tried to remove anything specific and just leave the example parts, so forgive me if it's missing anything or whatever, but it should give you an idea of how this works).
<?xml version="1.0"?>
<project name="jsonExample" default="all">
<target name="all" depends="example" />
<target name="example">
<!-- This uses Rhino - an Open Source implementation of JavaScript written in Java -
to parse JSON. -->
<script language="javascript"> <![CDATA[
importClass(java.io.File);
importClass(java.io.FileReader);
importClass(java.io.BufferedReader);
importClass(java.io.FileWriter);
importClass(java.io.BufferedWriter);
var file = new File("/path/to/myJSON.js");
fr = new FileReader(file);
br = new BufferedReader(fr);
// Read the file we just retrieved from the webservice that contains JSON.
var json = br.readLine();
// Evaluate the serialized JSON
var struct = eval("(" + json + ")");
// Get the data from
var value = struct.data.VALUE;
echo = example.createTask("echo");
echo.setMessage("Value = " + value);
echo.perform();
]]>
</script>
</target>
You can use a <script> task to run JavaScript to decode your JSON.
Here is the macro I use to load json-properties.
<macrodef name="json-properties">
<attribute name="jsonFile"/>
<sequential>
<local name="_jsonFile"/>
<property name="_jsonFile" value="#{jsonFile}"/>
<script language="javascript">//<![CDATA[
var json = new Packages.java.lang.String(
Packages.java.nio.file.Files.readAllBytes(
Packages.java.nio.file.Paths.get(project.getProperty("_jsonFile"))), "UTF-8");
var properties = JSON.parse(json);
for(key in properties) {
project.setProperty(key, properties[key]);
}
//]]></script>
</sequential>
</macrodef>