XPath/JSONPath search of arrays - json

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

Related

How Do I Structure This JSON CloudFormation Template

From this article, it shows how to deploy a AWS::Serverless::Function as a 'proxy' to do routing, a/b testing, etc.
The example template is in YAML, but we need to use JSON as that is what the AWS dotnet templates are built on.
There is a line in the YAML that I cannot figure out how to translate to a JSON template:
LambdaFunctionARN: !Ref LambdaEdgeFunctionSample.Version
In a JSON template a Ref just refers to another resource or parameter. You cannot Ref to a Resource.Property. For that you use Fn::GetAtt.
I have tried Fn::GetAtt, but that errors with "Version is an unknown attribute for this resource" (in the editor) and Template error: every Fn::GetAtt object requires two non-empty parameters, the resource name and the resource attribute during deployment:
"LambdaFunctionARN":{"Fn::GetAtt":["LambdaEdgeFunctionSample","Version"]}}
Mind you, these are both using AWS::Serverless::Function underneath, so there's more transforming going on.
Specifically, when the JSON template is transformed, it does create:
"LambdaEdgeFunctionSampleVersion1cfc342538": {
"Type": "AWS::Lambda::Version",
"DeletionPolicy": "Retain",
"Properties": {
"FunctionName": {
"Ref": "LambdaEdgeFunctionSample"
}
}
},
But I cannot use LambdaEdgeFunctionSampleVersion1cfc342538 as clearly that is a transient id.
How can I accomplish the same as the YAML template in a JSON template?
Apparently, AWS SAM does a transformation on !Ref LambdaEdgeFunctionSample.Version before the template is actually processed.
So, in Json, it's the same and SAM does the transformation:
{"Ref":"LambdaEdgeFunctionSample.Version"}
transforms to
{
"Ref": "LambdaEdgeFunctionSampleVersionf76b18e3ba"
}

Azure APIM : Convert JSON Response to Customized XML Format

I have a requirement where I want to convert the JSON response , which is an array of object , to the customized XML format , so that my already existing code can parse it.
I know there is a Azure Transformation Policy named <json-to-xml /> , but there is no customization possible with it.
Sample JSON Response:
{
"data":[
{"a":1,"b":2},
{"a":3,"b":4}
],
"param2": "Success",
"param3": "true"
}
Desired XML Format:
<result>
<sub-res>
<res x="a" y=1>
<res x="b" y=2>
</sub-res>
<sub-res>
<res x="a" y=3>
<res x="b" y=4>
</sub-res>
</result>
I have tried using the liquid template as well but no success. Need guidance or pointers on this.
For this requirement, I created an api which response {"data":[{"a":1,"b":2},{"a":3,"b":4}]} to simulate your situation.
Then I use a <json-to-xml> in APIM policy first, the response will be convert to xml shown as below after the <json-to-xml> policy:
<Document>
<data>
<a>1</a>
<b>2</b>
</data>
<data>
<a>3</a>
<b>4</b>
</data>
</Document>
After that, use xslt to convert the xml to which you want.
Below is all of policy in my APIM for your reference:
The result of APIM show as what you want:

Map file in the Integration for the LogicApp in Azure

Have the following XML as a result of the HTTP GET function from the B2B supplier.
<Invoices xmlns="http://gateway.com/schemas/Invoices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://gateway..com/schemas/Invoices Invoices.xsd">
<DocumentInfo>
<DocType>INVOICES</DocType>
<DocVersion>2.0</DocVersion>
</DocumentInfo>
<Header>
<StartDate>2018-12-01T00:00:00+01:00</StartDate>
<EndDate>2019-01-03T00:00:00+01:00</EndDate>
</Header>
<Documents>
<Invoice InvoiceId="RP82807" InvoiceDate="2019-01-02T00:00:00+01:00" DocumentType="IN" RefDocId="FT34532" RefDocType="ORDER" SystemId="10" HasPDFImage="0" />
<Invoice InvoiceId="T609881" InvoiceDate="2018-12-31T00:00:00+01:00" DocumentType="IN" RefDocId="FT39339" RefDocType="ORDER" SystemId="0" HasPDFImage="0" />
</Documents>
</Invoices>
Based on this article I've created the liquid map file to get the list of InvoiceIds:
{
"Invoice": "{{content.Documents.Invoice}}"
}
When using it in the LogicApp in the XML->Json converter, got the following result:
{
"Invoice": ""
}
I have also tried this as a liquid file:
{
"Invoice": "{{content.Invoices.Documents}}"
}
and this:
{
"Invoice": "{{content.Invoices.Documents.Invoice}}"
}
with the same result.
Can you give me a tip what I do wrong?
I tried to transfer part of your xml file to json with this map:
{
"DocType":"{{content.DocumentInfo.DocType}}",
"Invoice":"{{content.Documents.Invoice}}"
}
And get the output:
{
"DocType": "INVOICES",
"Invoice": ""
}
So this means I can get the DocType but can't get Invoice properties, so I think maybe the Liquid map doesn't support the XML format. Maybe you could change it to like this:
<Invoice>
<InvoiceId>T609881</InvoiceId>
<InvoiceDate>2018-12-31T00:00:00+01:00</InvoiceDate>
<DocumentType>IN</DocumentType>
<RefDocId>FT39339</RefDocId>
</Invoice>
This will work, or you could go to Liquid reference to check is there any methods to match the properties.
Note:what you want for now,binding to Xml Attributes is not currently supported.You could refer to this answer.
If you still have other questions, please let me know.
UPDATE:You still could do it with logic app. For example I used a FTP connector to get xml file content then create a json with "json(xml(body('Get_file_content')))" expression.
And this is the result.

How to generate a Swagger #definition from sample JSON

Take the following #definition from the pet store example. Given a #definition section a JSON structure can be generated
e.g.
Is there something that can do the reverse given a largeish complex JSON file?
Given the below JSON Structure can I get the #defintion section of a swagger file generated to save some typing
{
"variable": "sample",
"object1": {
"obj-field1": "field 1 of object",
"obj-field2": "field 2 of object",
"anArray": [
"Value 1",
{
"anArrayObj1": "obj1fieldinarray",
"anArrayObj2": "obj2fieldinarray"
}
]
}
}
You can use this JSON-to-OpenAPI schema converter:
https://roger13.github.io/SwagDefGen/
(GitHub project)
I haven't used it personally though, so I'm not sure how good it is.
Since OpenAPI uses a subset of JSON Schema, you could also use one of the JSON Schema generators, however you may need to manually tweak the generated definition to make it OpenAPI-compatible.
1 - Paste a response in http://www.mocky.io and get a link to your response
2 - Go to https://inspector.swagger.io/ and make a call to your example response
3 - Select the call from "History" and click "Create API definition"
4 - The swagger definition will be available at https://app.swaggerhub.com/
You can use mock-to-openapi cli tool that generates OpenAPI YAML files from JSON mock.
npm install --global mock-to-openapi
then run the conversion of all *.json files from the folder:
mock-to-openapi ./folder/*.json`
Let's have, for example, json object with:
{
"title": "This is title",
"author": "Roman Ožana",
"content" : "This is just an example",
"date": "2020-05-12T23:50:21.817Z"
}
Tool mock-to-openapi converts JSON to the OpenAPI specification as follows:
type: object
properties:
title:
type: string
example: This is title
author:
type: string
example: Roman Ožana
content:
type: string
example: This is just an example
date:
type: string
format: date-time
example: 2020-05-12T23:50:21.817Z
This works for me:
Generate Swagger REST-client code (and POJO) from sample JSON:
Go to apistudio.io:
Insert -> New Model.
CutNpaste your JSON.
[The Swagger YML file will be generated]
Download -> YAML.
Go to editor.swagger.io:
CutNpaste the YML saved from last step.
Generate Client -> jaxrs-cxf-client (there are many other options).

Building json path expression - presence of DOT in attribute name

We are working with a legacy system which gives json responses. We trying to test these json endpoints with jmeter. So, we are trying to use the json path extractor plugin for the purpose. But the structure of the json path is causing an issue in creating json path expressions.
The structure of the json which we are receiving from the server is as follows.
{
"ns9.Shopping": {
"transactionID": "XXXXXNEKIHJO7SRHN1",
"transactionStatus": "Success",
"ns9.shoppingResponseIDs": {
"ns9.owner": "1P",
"ns9.responseId": "abcdefghijklmnop"
},
"ns9.offersGroup": {"ns9.thanksGiving": [
{
"ns9.owner": "DL",
"ns9.retailOffer": [
{
"ns9.offerId": "offer1DL",
"ns9.price": 2639.08,
"ns9.currencyCode": "USD",
"ns9.taxTotal": 961.08,
"ns9.taxCode": "USD",
.........
The presence of . [DOT] in the attribute name is causing issues in my json path expression.
In short, can some one help in finding the "transactionID" from "ns9.Shopping"?
You can try to add Regular Expression Extractor within your HTTP Request element.
Put this regex:
"transactionID": "([a-zA-Z0-9]*)"
I hope this will help you.