This thing drove me crazy. Batsh!t insane, but it is all better now because I found the solution.
The issue
You need to call a SOAP service that uses XML and you want to use Liquid templates instead of XSLT. You use the SOAP passthru as it is the most flexible way of calling a SOAP service.
The response body might look a little like this:
<Soap:Envelope xmlns:Soap="http://schemas.xmlsoap.org/soap/envelope/">
<Soap:Body>
<ns0:PriceList_Response xmlns:ns0="myNamespace">
<PriceList>
<companyId>1</companyId>
<prices>
<price>
<productId>QWERTY123</productId>
<unitPrice>1900.00</unitPrice>
<currency>EUR</currency>
</price>
</prices>
</PriceList>
</ns0:PriceList_Response>
</Soap:Body>
</Soap:Envelope>
You transform the payload into JSON and what to put it thru a Liquid template.
{
"Soap:Envelope": {
"@xmlns:Soap": "http://schemas.xmlsoap.org/soap/envelope/",
"Soap:Body": {
"ns0:PriceList_Response": {
"@xmlns": "myNamespace",
"PriceList": {
"companyId": {
"#text": "1"
},
"prices": {
"price": {
"productId": "1",
"unitPrice": "19.00",
"currency": "DKK"
}
}
}
}
}
}
}
How do you access the price
property, in this payload? This will not work:
{{ content.Soap:Envelope.Soap:Body.ns0:PriceList_Response.prices.price.unitPrice }}
That is because the colon is a special char in Liquid templates and I found no way of escaping it.
The solution
{{ content.['Soap:Envelope'].['Soap:Body'].['ns0:PriceList_Response'].prices.price.unitPrice }}
I was so happy not to be insane anymore.
A tip
Accessing properties deep in a document can be quite confusing and unclear if you need to use a string to get property values in your Liquid template. Use the ability to assign
an object to a variable. This means that you can get a Liquid template that looks like this. It is used for assigning price
using the payload above:
{% assign price = content.['Soap:Envelope'].['Soap:Body'].['ns0:PriceList_Response'].prices.price.unitPrice %}
"prices": [
{
"ProdId": "{{price.productId}}",
"ProdPrice": "{{price.unitPrice}}",
"Curr": "{{price.currency}}"
}
]