How would I validate if my JSON object has another object or and Array, using Liquid Template

698 views Asked by At

I am currently trying to find a way to validate if my JSON object has another object in it or an array while using liquid templates.

I am using the xml-to-json policy which takes my below xml and turns it into JSON

  <additional-data-set>
    <additional-data>
      <name>LodgementDate</name>
      <value>24/04/2019 00:00:00 NZST</value>
    </additional-data>
  </additional-data-set>

Converted to JSON

"additional-data": {
        "name": "LodgementDate",
        "value": "24/04/2019 00:00:00 NZST"
    }

However when I add an additional-data to it i get the below

  <additional-data-set>
    <additional-data>
      <name>LodgementDate</name>
      <value>24/04/2019 00:00:00 NZST</value>
    </additional-data>
    <additional-data>
      <name>LodgementDate1</name>
      <value>25/05/2019 00:00:00 NZST</value>
    </additional-data> 
  </additional-data-set>

Converted to JSON

"additional-data": [
        {
            "name": "LodgementDate",
            "value": "24/04/2019 00:00:00 NZST"
        },
        {
            "name": "LodgementDate1",
            "value": "25/05/2019 00:00:00 NZST"
        }
    ],

As you can see it goes from being an object to an array when there is two or more additional-data.

I am currently trying the below code to validate it as an array or not

{
{% assign ads = body["p$ReadECODetailsResponse"].additional-data-set %}

"additional-data-set": {
            "additional-data": [

            {% if ads.additional-data.size < 0 %}
           {% for addDataBody in ads.additional-data %}
            {   
                "name": "{{addDataBody.name}}",
                "value": "{{addDataBody.value}}"
            }{% if forloop.last != true %},{% endif %}
            {% endfor %}
            {% break %}

            {% else %}
            {
                "name": "{{ads.additional-data.name}}",
                "value": "{{ads.additional-data.value}}"
            }
            {% break %}
            {% endif %}
            ]
        }
}

My problem is, the template cannot distinguish between the object and the array. And when calling each type (1 additional-data or 2 additional-data) the data will not call and be templated due to it not staying as an object/array.

Any ideas?

2

There are 2 answers

0
Pankaj More On BEST ANSWER

If the liquid template is directly used in the Azure APIM, it has difference about how the array elements are handled. Using the JSONArrayfor tag should solve your problem. Please find below working code in the above example:

[
            {% JSONArrayFor item in body.additional-data-set %}
                {
                    "name": "{{item.name}}",
                    "value": "{{item.value}}"
                }
            {% endJSONArrayFor %}]
3
Pankaj More On

Liquid template allows you to directly work on the XML objects. In this example you can directly iterate the input and read the values, without any overhead. Please find below liquid code, which always returns an array.

[
{% for item in content.additional-data-set %}
    {
        "name": "{{item.name}}",
        "value": "{{item.value}}"
    },
{% endfor %}]

The liquid template output snapshots: In a single : enter image description here For multiple objects: enter image description here