# Parsing JSON/XML from web responses

**URL:** <https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268>\
**Category:** General Q&A\
**Created:** [September 7, 2019, 2:57pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268 "2019-09-07T14:57:31Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [September 7, 2019, 2:57pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/1 "2019-09-07T14:57:31Z")

</div>

Since with the introduction of Web Request / Iterate Web Request we are now in the business of dealing with external RESTful APIs, for our users it will be necessary at some point to parse incoming JSONs as well as generate JSONs too. We will be introducing dedicated actions for parsing JSON in version 4.1. They won't be available in 4.0. I know it kind of sucks but we couldn't delay releasing v4.0 - it's already late 🙄

To alleviate the problem a little, we've added two new functions - jsonvalue() and xmlvalue(). They can extract single values from JSON or XML using [JSONPath](https://goessner.net/articles/JsonPath/) or XPath respectively. Examples:

```
jsonvalue("{customer:{ID:345}}", "customer.ID") returns 345

xmlvalue("<CUSTOMER><ID>345</ID></CUSTOMER>", "CUSTOMER/ID") returns 345

```

[json-xml-value.morph](https://community.easymorph.com/uploads/short-url/e90RGBjGWWoHKCzUXuCT0xhR9hI.morph) (2.5 KB)

 ![image](https://community.easymorph.com/uploads/default/original/2X/a/aa4b2048dd944ba06e0318051de329305c55b708.png)

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [September 10, 2019, 5:45am UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/2 "2019-09-10T05:45:13Z")

</div>

A post was merged into an existing topic: [Example: Constructing JSON](https://community.easymorph.com/t/example-constructing-json/1279/2)

---

<div class="post-metadata">

**Author:** ![adambeltz](https://community.easymorph.com/user_avatar/community.easymorph.com/adambeltz/32/3678_2.png) [@adambeltz](https://community.easymorph.com/u/adambeltz)\
**Post date:** [September 9, 2019, 2:53am UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/3 "2019-09-09T02:53:44Z")

</div>

Hi @dgudkov -

I'm looking at the JSON file that would be a typical response back in a flat example:  
Something like this:

Sample from Magento GET Inventory by SKU  
{"item\_id":953294,"product\_id":690692,"stock\_id":1,"qty":99,"is\_in\_stock":true,"is\_qty\_decimal":false,"show\_default\_notification\_message":false,"use\_config\_min\_qty":true,"min\_qty":10,"use\_config\_min\_sale\_qty":1,"min\_sale\_qty":1,"use\_config\_max\_sale\_qty":true,"max\_sale\_qty":10000,"use\_config\_backorders":true,"backorders":0,"use\_config\_notify\_stock\_qty":true,"notify\_stock\_qty":11,"use\_config\_qty\_increments":true,"qty\_increments":0,"use\_config\_enable\_qty\_inc":true,"enable\_qty\_increments":false,"use\_config\_manage\_stock":true,"manage\_stock":true,"low\_stock\_date":null,"is\_decimal\_divided":false,"stock\_status\_changed\_auto":0}

So in order to use this function we would have to parse out each of the columns and then run the function on it, correct?

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [September 9, 2019, 6:56am UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/4 "2019-09-09T06:56:58Z")

</div>

> [@adambeltz](#):
>
> Sample from Magento GET Inventory by SKU  
> {“item\_id”:953294,“product\_id”:690692,“stock\_id”:1,“qty”:99,“is\_in\_stock”:true,“is\_qty\_decimal”:false,“show\_default\_notification\_message”:false,“use\_config\_min\_qty”:true,“min\_qty”:10,“use\_config\_min\_sale\_qty”:1,“min\_sale\_qty”:1,“use\_config\_max\_sale\_qty”:true,“max\_sale\_qty”:10000,“use\_config\_backorders”:true,“backorders”:0,“use\_config\_notify\_stock\_qty”:true,“notify\_stock\_qty”:11,“use\_config\_qty\_increments”:true,“qty\_increments”:0,“use\_config\_enable\_qty\_inc”:true,“enable\_qty\_increments”:false,“use\_config\_manage\_stock”:true,“manage\_stock”:true,“low\_stock\_date”:null,“is\_decimal\_divided”:false,“stock\_status\_changed\_auto”:0}

In this case it's a flat JSON, so it can be trivially parsed using EasyMorph transformations. See below the JSON parsed.

[parse-flat-json.morph](https://community.easymorph.com/uploads/short-url/6ftyNHFkbIwRqPFtqQtKHHBu3jl.morph) (3.4 KB)

 ![image](https://community.easymorph.com/uploads/default/original/2X/e/e018ff2b390aa4eecd3c12a27fd02a91007437d0.png)

Parsing a nested hierarchical JSON would be trickier (until we introduce the "Parse JSON" action) and would probably require a combination of actions and functions.

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [September 9, 2019, 11:04am UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/5 "2019-09-09T11:04:10Z")

</div>

A post was split to a new topic: [Constructing JSON](https://community.easymorph.com/t/constructing-json/1279)

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [September 10, 2019, 5:46am UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/6 "2019-09-10T05:46:55Z")

</div>

A post was merged into an existing topic: [Example: Constructing JSON](https://community.easymorph.com/t/example-constructing-json/1279/4)

---

<div class="post-metadata">

**Author:** ![cvo](https://community.easymorph.com/letter_avatar_proxy/v4/letter/c/a88e57/32.png) [@cvo](https://community.easymorph.com/u/cvo)\
**Post date:** [September 13, 2019, 3:10pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/7 "2019-09-13T15:10:32Z")

</div>

So far it's really good.  
I can extract metadata and data from IBM Planning Analytics/TM1  
very useful.

---

<div class="post-metadata">

**Author:** ![DKcrm](https://community.easymorph.com/user_avatar/community.easymorph.com/dkcrm/32/978_2.png) [@DKcrm](https://community.easymorph.com/u/DKcrm)\
**Post date:** [October 3, 2019, 6:52pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/8 "2019-10-03T18:52:03Z")

</div>

Looking for guidance on the nested JSON (until introduction of the Parse action) - Is this something already available to work with?

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [October 3, 2019, 7:21pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/9 "2019-10-03T19:21:25Z")

</div>

To some extent. There are 3 options available how to extract data from nested JSONs until introduction of the Parse action (which is a big-big priority for us):

1. Usual transformations and text functions that existed before 4.0.
2. Function jsonvalue() described above - one function would be necessary per each nested value.
3. Parsing JSON with PowerShell.

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [October 10, 2019, 9:04pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/10 "2019-10-10T21:04:25Z")

</div>

\*\*\*\*\* moved from #Beta lounge to #General Q&A

---

<div class="post-metadata">

**Author:** ![reynsnivea](https://community.easymorph.com/letter_avatar_proxy/v4/letter/r/9f8e36/32.png) [@reynsnivea](https://community.easymorph.com/u/reynsnivea)\
**Post date:** [November 18, 2019, 1:57pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/11 "2019-11-18T13:57:57Z")

</div>

Tip to find the jsonpath quickly:

> **[JSON Path Finder](https://jsonpathfinder.com/)**
>
> JSON Path Finder

---

<div class="post-metadata">

**Author:** ![reynsnivea](https://community.easymorph.com/letter_avatar_proxy/v4/letter/r/9f8e36/32.png) [@reynsnivea](https://community.easymorph.com/u/reynsnivea)\
**Post date:** [November 18, 2019, 2:25pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/12 "2019-11-18T14:25:06Z")

</div>

Hi Dmitry,

What's the JSON path expression to filter only the objectId for de 2 items with objectType = Gebouweenheid in this array ?  
How can I apply a filter in some way I always get errors?

I have tried the following but it throws an error. Maybe somethting with the quotes ?

jsonvalue(  
[Response-Body],  
'adresMatches[0].adresseerbareObjecten[?(@.objectType)=="Gebouweenheid"].objectId'  
)

 ![image](https://community.easymorph.com/uploads/default/original/2X/2/2c073cdd1773704bcfff6393b7def0a1a04fb4c1.png)

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [November 18, 2019, 4:57pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/13 "2019-11-18T16:57:10Z")

</div>

Hi Nikolaas,

wait for the "Parse JSON" action in v4.1. While JSONPath expressions can be quite powerful, we will be recommending using "Parse JSON" and apply regular EasyMorph actions.

---

<div class="post-metadata">

**Author:** ![reynsnivea](https://community.easymorph.com/letter_avatar_proxy/v4/letter/r/9f8e36/32.png) [@reynsnivea](https://community.easymorph.com/u/reynsnivea)\
**Post date:** [November 18, 2019, 8:44pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/14 "2019-11-18T20:44:56Z")

</div>

Hi

I understand that but I would like to use it now....

When I do the following it works when I test it in the online tool (without the surrounding quotes) [https://jsonpath.curiousconcept.com/](https://jsonpath.curiousconcept.com/)  
In easyMorph I get an error. What could be the reason?

'adresMatches[0].adresseerbareObjecten[?(@.objectType=="Gebouweenheid")]'

jsonvalue(  
[json], 'adresMatches[0].adresseerbareObjecten[?(@.objectType=="Gebouweenheid")]'  
)

---

<div class="post-metadata">

**Author:** ![andrew.rybka](https://community.easymorph.com/user_avatar/community.easymorph.com/andrew.rybka/32/13_2.png) [@andrew.rybka](https://community.easymorph.com/u/andrew.rybka)\
**Post date:** [November 19, 2019, 2:13pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/15 "2019-11-19T14:13:01Z")

</div>

Hi Nikolaas,

Strings in filters should be wrapped in single quotes, not double quotes.

Try to replace `“Gebouweenheid”` with `'Gebouweenheid'` and wrap the whole JSONPath query to double quotes instead of single quotes.

---

<div class="post-metadata">

**Author:** ![reynsnivea](https://community.easymorph.com/letter_avatar_proxy/v4/letter/r/9f8e36/32.png) [@reynsnivea](https://community.easymorph.com/u/reynsnivea)\
**Post date:** [November 20, 2019, 9:43am UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/16 "2019-11-20T09:43:32Z")

</div>

> [@reynsnivea](#):
>
> ‘adresMatches[0].adresseerbareObjecten[?(@.objectType==“Gebouweenheid”)]’

Works great ! I thought it was something with the quotes but I did not try your option;

---

<div class="post-metadata">

**Author:** ![reynsnivea](https://community.easymorph.com/letter_avatar_proxy/v4/letter/r/9f8e36/32.png) [@reynsnivea](https://community.easymorph.com/u/reynsnivea)\
**Post date:** [November 20, 2019, 10:12am UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/17 "2019-11-20T10:12:55Z")

</div>

When I use iterate webrequest on a table, the output of the request overwrites my table. How can I recover the original columns? The output of the webrequest should be appended as columns to my originial table because the original columns are used as parameters in the web request.

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [November 20, 2019, 3:03pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/18 "2019-11-20T15:03:29Z")

</div>

All iterate actions (e.g. "Iterate" or "Iterate table" replace input datasets. If you want to have it back merged with iteration results you do iterations in a derived table, then merge the original data using the "Merge" action.

To help with that, the "Iterate web request" action allows adding request path, body and headers (see the option below).

 ![image](https://community.easymorph.com/uploads/default/original/2X/f/f9a6beadb525288358e0054bcc4b914ec5a56e34.png)

---

<div class="post-metadata">

**Author:** ![reynsnivea](https://community.easymorph.com/letter_avatar_proxy/v4/letter/r/9f8e36/32.png) [@reynsnivea](https://community.easymorph.com/u/reynsnivea)\
**Post date:** [November 20, 2019, 7:35pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/19 "2019-11-20T19:35:10Z")

</div>

Hi Dmitry,

The problem that I have is the following:

I send address data to an API using iterate webrequest. That returns an ID of the address and other properties such as GPS coordinates,...

The matching of the API is "intelligent" in a way because when I send a street name like "Andre Schottplein" the API returns in the reponse Andr **é** Schotteplein. So it returns the name of the street with the correct spelling i.e. with "é" in "André". Because of that fact, I can no longer match my orinigal dataset wich has the value without the special character to the output of the web request.

When I try to get it from the request path, that special character is also transformed to "%20" in the url. Any suggestions how I could get the original values back so that I can add the data returned from the API to my original dataset?

[https://basisregisters.vlaanderen.be/api/v1/adresmatch?adresMatchRequest.postcode=9620&adresMatchRequest.straatnaam=Andre\*\*%20\*\*Schotteplein](https://basisregisters.vlaanderen.be/api/v1/adresmatch?adresMatchRequest.postcode=9620&adresMatchRequest.straatnaam=Andre **%20** Schotteplein)

Maybe I should use the decode() function here ?

---

<div class="post-metadata">

**Author:** ![dgudkov](https://community.easymorph.com/user_avatar/community.easymorph.com/dgudkov/32/5_2.png) [@dgudkov](https://community.easymorph.com/u/dgudkov)\
**Post date:** [November 20, 2019, 9:14pm UTC](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268/20 "2019-11-20T21:14:08Z")

</div>

First, you can use the [decode()](http://help.easymorph.com/doku.php?id=syntax:functions:decode) or [uridecode()](http://help.easymorph.com/doku.php?id=syntax:functions:uridecode) functions to get rid of %20.

Second, if you use the option I mentioned earlier, you can link requests to responses. You may need to parse requests to extract keys but it will give you the relationship between what you send and what you receive. In this case you can do matching not by response data (which is modified in your case), but by request data (which unmodified in your case).

[Next page](https://community.easymorph.com/t/parsing-json-xml-from-web-responses/1268.md?page=2)
