Insight

Parse JSON messages without root element with Logic Apps

During one of our Logic App projects we faced an issue with trying to parse JSON messages without root element.

In this blog post we will describe one of the solutions we implemented in order to process those messages.

Looking at the workflow definition language you can expect the xml to be able to translate JSON objects to xml and vice versa. Though not every structure can be parsed into an xml.

data = {
    "values": [
        {
            "name": "Manu",
            "lastName": "De Deyn",
            "occupation": None
        },
        {
            "name": "Jochen",
            "lastName": "Toelen",
            "occupation": None
        }
    ]
}

When we try to parse this JSON we receive the following error:

InternalServerError. Encountered internal server error. The tracking Id is …

This error message however does not give a clear indication as to why the JSON file can’t be parsed

The workflow definition function xml can’t handle JSON files that does not specify a root node element. Though specifying a Deserialize RootElement Name is not supported in the xml function which only takes one parameter.

Thankfully we can solve all this by simply using the workflow definition language.

We need to manipulate the JSON string and concatenate a root node name onto it.

So in this example I simply post a the above JSON to a HTTP listener inside our logic app an subsequently try to parse it to xml

This means that we have to concat { “rootNode” : at the front and an extra } at the end. Which turns our json example into the one below.

data = {
    "rootNode": {
        "values": [
            {
                "name": "Manu",
                "lastName": "De Deyn",
                "occupation": None
            },
            {
                "name": "Jochen",
                "lastName": "Toelen",
                "occupation": None
            }
        ]
    }
}

Directly inserting this into the workflow function @xml however does not work since this only accepts an xml string or a json object. So, we first have to parse this into a JSON object before we can parse it to XML.

@xml(json(string(concat(‘{ “rootNode”: ‘, string(concat(string(body(‘Get_records’)), ‘}’))))))

Which then turns into the following xml output:

<?xml version="1.0" encoding="UTF-8"?>
<rootNode>
   <values>
      <name>Manu</name>
      <lastName>De Deyn</lastName>
      <occupation/>
   </values>
   <values>
      <name>Jochen</name>
      <lastName>Toelen</lastName>
      <occupation/>
   </values>
</rootNode>

Conclusion

With this approach, we could parse JSON messages without root element without the need to implement additional components. In a following blog post we will describe how the same result can be achieved through Azure Functions.

Other .insights