0

I've encountered a problem regarding mapping values using liquid for a "Soap to Rest" api endpoint in API management policys.

My Example looks something like this...

The Soap Request should return something like this:

<Response>
    <Truck>
        <ID>098NJ2139UND324<ID>
        <LicenceNumber>MKL025</LicenceNumber>
        <Cargo>
            <CargoLicenceNumber>BHJ897</CargoLicenceNumber>
            <Cargo>Candy</Cargo>
        </Cargo>
        <Cargo>
            <CargoLicenceNumber>TGA916</CargoLicenceNumber>
            <Cargo>Fireworks</Cargo>
        </Cargo>    
    </Truck>
</Response>

My Liquid Code sample in the "out" policy in API management looks something like this:

{
    "Response": {
        "id": "{{body.envelope.body.Response.ID}}",
        "licencenumber": "{{body.envelope.body.Response.LicenceNumber}}",
        "cargo": [
        {% JSONArrayFor item in body.envelope.body.Response where Cargo -%}
        {
            "cargolicencenumber": "{{item.CargoLicenceNumber}}",
            "cargo": "{{item.Cargo}}"
        }
        {% endJSONArrayFor -%}
        ]
    }
}

But the converted XML to Json looks like this:

{
    "Response":{
        "ID": "098NJ2139UND324",
        "LicenceNumber": "MKL025",
        "Cargo": [{
                "CargoLicenceNumber": "BHJ897",
                "Cargo":""
            },
            {
                "CargoLicenceNumber": "TGA916",
                "Cargo":""
            }
        ]
    }
}

I'm missing this "Cargo" value in the array. I know The Setup is a bit clunky as i think the name of the array object "Cargo" should be "Trailer" or something like that (NOTE: This is an example, not the real object I'm working with). The Array having the same name as the array Sub-element is what i think is causing the problem.

As I'm not the owner of the SOAP WSDL i used to import to API management to in turn convert to a rest API, I cant easily change the name of the Array in the service. There for I'm wondering if there is a way to force liquid to find the value of the element in the array some how?

Also, worth mentioning is: as i was troubleshooting the code i changed the "{{item.Cargo}}" part to "{{item.CargoLicenceNumber}}" and that found the license plate number without any problems. So I'm thinking something in the back end is definitely getting confused by the name of the property.

Has anyone else encountered this problem before?

Thanks in advance.

H4p7ic
  • 1,669
  • 2
  • 32
  • 61

1 Answers1

1

It seems that the back end cannot handle xml property very well.

Based on my test, if we use xml-to-json policy and then use liquid template to handle it, the backend will be able to get the sub-element "Cargo" for you.

Here is my sample policy for your reference:

<outbound>
    <base />
    <xml-to-json kind="direct" apply="always" consider-accept-header="false" />
    <set-body template="liquid">
    {
        "Response": {
            "id": "{{body.Response.Truck.ID}}",
            "licencenumber": "{{body.Response.Truck.LicenceNumber}}",
            "cargo": [
            {% JSONArrayFor item in body.Response.Truck.Cargo %}
                {
                    "cargolicencenumber": "{{item.CargoLicenceNumber}}",
                    "cargo": "{{item.Cargo}}"
                }
            {% endJSONArrayFor %}
            ]
        }
    }
    </set-body>
</outbound>
Allen Wu
  • 15,529
  • 1
  • 9
  • 20
  • Thanks for you answer @AllenWu, It doesnt work in my end the values are not accessable when after implementing the "Xml-to-Json" element before thew "set-body" one. – H4p7ic Jun 08 '20 at 13:59
  • @John It works fine for me. Your Soap response has an error. `098NJ2139UND324` should be modified to `098NJ2139UND324`. If it still doesn't work, please share your real Soap response and the APIM policy you are using now. – Allen Wu Jun 09 '20 at 01:23
  • Hello @Allen sorry for the late answer, well what i did was only using the "xml-to-json" conversion directly and then set the "set-body" part in my policy to the body returned by the conversion method from the context. and that returned the correct json-string i needed. For some reason using the "template=liqud" in my "set-body" tag wouldnt for the life of me understand how to enter the context go get the values, instead it returned the whole root property empty. I'm using Soap to rest so i think there is a lot going on in the back that messes things up reference-wise. – H4p7ic Jun 11 '20 at 11:02
  • Also I'm afraid i cant show the data I'm using as its related to an integration for a company I'm working for. – H4p7ic Jun 11 '20 at 11:03
  • @John No problem. In fact, the only thing I modified was this: `{% JSONArrayFor item in body.envelope.body.Response where Cargo -%}` to `{% JSONArrayFor item in body.Response.Truck.Cargo %}`. Please check it. – Allen Wu Jun 12 '20 at 01:49