Transform JSON and XML using Liquid templates as maps in workflows using Azure Logic Apps
Applies to: Azure Logic Apps (Consumption + Standard)
When you want to perform basic JSON transformations in your logic app workflows, you can use built-in data operations, such as the Compose action or Parse JSON action. However, some scenarios might require advanced and complex transformations that include elements such as iterations, control flows, and variables. For transformations between JSON to JSON, JSON to text, XML to JSON, or XML to text, you can create a template that describes the required mapping or transformation using the Liquid open-source template language. You can select this template when you add a Liquid built-in action to your workflow. You can use Liquid actions in multitenant Consumption logic app workflows and single-tenant Standard logic app workflows.
While no Liquid triggers are available, you can use any trigger or action to feed the source JSON or XML content into your workflow. For example, you can use a built-in connector trigger, a managed or Azure-hosted connector trigger available for Azure Logic Apps, or even another app.
This article shows how to complete the following tasks:
- Create a Liquid template.
- Upload the template to your integration account for Consumption logic app workflows or to your Standard logic app resource for use in any child workflow.
- Add a Liquid action to your workflow.
- Select the template as the map that you want to use.
For more information, review the following documentation:
- Perform data operations in Azure Logic Apps
- Liquid open-source template language
- Consumption versus Standard logic apps
- Integration account built-in connectors
- Built-in connectors overview for Azure Logic Apps
- Managed or Azure-hosted connectors overview for Azure Logic Apps and Managed or Azure-hosted connectors in Azure Logic Apps
Prerequisites
An Azure account and subscription. If you don't have a subscription, sign up for a free Azure account.
Your logic app resource and workflow. Liquid operations don't have any triggers available, so your workflow has to minimally include a trigger. For more information, se the following documentation:
Based on whether you're working on a Consumption or Standard logic app workflow, you'll need an integration account resource. Usually, you need this resource when you want to define and store artifacts for use in enterprise integration and B2B workflows.
Important
To work together, both your integration account and logic app resource must exist in the same Azure subscription and Azure region.
If you're working on a Consumption logic app workflow, your integration account requires a link to your logic app resource.
If you're working on a Standard logic app workflow, you can link your integration account to your logic app resource, upload maps directly to your logic app resource, or both, based on the following scenarios:
If you already have an integration account with the artifacts that you need or want to use, you can link the integration account to multiple Standard logic app resources where you want to use the artifacts. That way, you don't have to upload maps to each individual logic app. For more information, review Link your logic app resource to your integration account.
The Liquid built-in connector lets you select a map that you previously uploaded to your logic app resource or to a linked integration account, but not both. You can then use these artifacts across all child workflows within the same logic app resource.
So, if you don't have or need an integration account, you can use the upload option. Otherwise, you can use the linking option. Either way, you can use these artifacts across all child workflows within the same logic app resource.
Basic knowledge about Liquid template language. Azure Logic Apps uses DotLiquid 2.0.361.
Note
The Liquid action named Transform JSON to JSON follows the DotLiquid implementation for Liquid, which differs in specific cases from the Shopify implementation for Liquid. For more information, see Liquid template considerations.
Install or use a tool that can send HTTP requests to test your solution, for example:
- Visual Studio Code with an extension from Visual Studio Marketplace
- PowerShell Invoke-RestMethod
- Microsoft Edge - Network Console tool
- Bruno
- curl
Caution
For scenarios where you have sensitive data, such as credentials, secrets, access tokens, API keys, and other similar information, make sure to use a tool that protects your data with the necessary security features, works offline or locally, doesn't sync your data to the cloud, and doesn't require that you sign in to an online account. This way, you reduce the risk around exposing sensitive data to the public.
Step 1: Create the template
Before you can perform a Liquid transformation in your logic app workflow, you must first create a Liquid template that defines the mapping that you want.
Create the Liquid template that you use as a map for the JSON transformation. You can use any editing tool that you want.
The JSON to JSON transformation example in this article uses the following sample Liquid template:
{%- assign deviceList = content.devices | Split: ', ' -%} { "fullName": "{{content.firstName | Append: ' ' | Append: content.lastName}}", "firstNameUpperCase": "{{content.firstName | Upcase}}", "phoneAreaCode": "{{content.phone | Slice: 1, 3}}", "devices" : [ {%- for device in deviceList -%} {%- if forloop.Last == true -%} "{{device}}" {%- else -%} "{{device}}", {%- endif -%} {%- endfor -%} ] }
Save the template using the Liquid template (.liquid) file extension. This example uses SimpleJsonToJsonTemplate.liquid.
Step 2: Upload Liquid template
After you create your Liquid template, you now have to upload the template based on the following scenario:
If you're working on a Consumption logic app workflow, upload your template to your integration account.
If you're working on a Standard logic app workflow, you can upload your template to your integration account, or upload your template to your logic app resource.
Upload template to integration account
In the Azure portal, sign in with your Azure account credentials.
In the Azure portal search box, enter integration accounts, and select Integration accounts.
Find and select your integration account.
On the integration account's navigation menu, under Settings, select Maps.
On the Maps pane, select Add. Provide the following information about your map:
Property Value Description Name JsonToJsonTemplate
The name for your map, which is "JsonToJsonTemplate" in this example Map type Liquid The type for your map. For JSON to JSON transformation, you must select Liquid. Map SimpleJsonToJsonTemplate.liquid
An existing Liquid template or map file to use for transformation, which is "SimpleJsonToJsonTemplate.liquid" in this example. To find this file, you can use the file picker. For map size limits, see Limits and configuration.
Upload template to Standard logic app
In the Azure portal, find and open your logic app resource. Make sure that you're at the resource level, not the workflow level.
On your logic app resource's navigation menu, under Artifacts, select Maps.
On the Maps pane toolbar, select Add.
On the Add Map pane, provide the following information about your template:
Property Value Description Name JsonToJsonTemplate
The name for your map, which is "JsonToJsonTemplate" in this example Map type Liquid The type for your map. For JSON to JSON transformation, you must select Liquid. Map SimpleJsonToJsonTemplate.liquid
An existing Liquid template or map file to use for transformation, which is "SimpleJsonToJsonTemplate.liquid" in this example. To find this file, you can use the file picker. For map size limits, see Limits and configuration. When you're done, select OK.
After your map file finishes uploading, the map appears in the Maps list. On your integration account's Overview page, under Artifacts, your uploaded map also appears.
Step 3: Add the Liquid transformation action
The following steps show how to add a Liquid transformation action for Consumption and Standard logic app workflows.
In the Azure portal, open your logic app workflow in the designer, if not already open.
If your workflow doesn't have a trigger or any other actions that your workflow needs, add those operations first. Liquid operations don't have any triggers available.
This example continues with the Request trigger named When a HTTP request is received.
On the workflow designer, under the step where you want to add the Liquid action, select New step.
Under the Choose an operation search box, select All. In the search box, enter liquid.
From the actions list, select the Liquid action that you want to use.
This example continues using the action named Transform JSON to JSON.
In the action's Content property, provide the JSON output from the trigger or a previous action that you want to transform by following these steps.
Click inside the Content box so that the dynamic content list appears.
From the dynamic content list, select the JSON data that you want to transform.
For this example, from the dynamic content list, under When a HTTP request is received, select the Body token, which represents the body content output from the trigger.
From the Map list, select your Liquid template.
This example continues with the template named JsonToJsonTemplate.
Note
If the maps list is empty, either your logic app resource isn't linked to your integration account or your integration account doesn't contain any map files.
When you're done, the action looks similar to the following example:
Save your workflow. On the designer toolbar, select Save.
Test your workflow
To trigger your workflow, follow these steps:
In the Request trigger, find the HTTP POST URL property, and copy the URL.
Open your HTTP request tool and use its instructions to send an HTTP request to the copied URL, including the method that the Request trigger expects.
This example uses the
POST
method with the URL.Include the JSON input to transform, for example:
{ "devices": "Surface, Mobile, Desktop computer, Monitors", "firstName": "Dean", "lastName": "Ledet", "phone": "(111)0001111" }
After your workflow finishes running, go to the workflow's run history, and examine the Transform JSON to JSON action's inputs and outputs, for example:
Other Liquid transformations
You can use Liquid to perform other transformations, for example:
Transform JSON to text
The following Liquid template shows an example transformation for JSON to text:
{{content.firstName | Append: ' ' | Append: content.lastName}}
The following example shows the sample inputs and outputs:
Transform XML to JSON
The following Liquid template shows an example transformation for XML to JSON:
[{% JSONArrayFor item in content -%}
{{item}}
{% endJSONArrayFor -%}]
The JSONArrayFor
loop is a custom looping mechanism for XML input so that you can create JSON payloads that avoid a trailing comma. Also, the where
condition for this custom looping mechanism uses the XML element's name for comparison, rather than the element's value like other Liquid filters. For more information, see Deep Dive on set-body Policy - Collections of Things.
The following example shows the sample inputs and outputs:
Transform XML to text
The following Liquid template shows an example transformation for XML to text:
{{content.firstName | Append: ' ' | Append: content.lastName}}
The following example shows the sample inputs and outputs:
Liquid template considerations
Liquid templates follow the file size limits for maps in Azure Logic Apps.
The Transform JSON to JSON action follows the DotLiquid implementation for Liquid. This implementation is a port to the .NET Framework from the Shopify implementation for Liquid and differs in specific cases.
The following list describes the known differences:
The Transform JSON to JSON action natively outputs a string, which can include JSON, XML, HTML, and so on. The Liquid action only indicates that the expected text output from the Liquid template's is a JSON string. The action instructs your logic app to parse input as a JSON object and applies a wrapper so that Liquid can interpret the JSON structure. After the transformation, the action instructs your logic app to parse the text output from Liquid back to JSON.
DotLiquid doesn't natively understand JSON, so make sure that you escape the backslash character (
\
) and any other reserved JSON characters.If your template uses Liquid filters, make sure that you follow the DotLiquid and C# naming conventions, which use sentence casing. For all Liquid transforms, make sure that filter names in your template also use sentence casing. Otherwise, the filters won't work.
For example, when you use the
replace
filter, useReplace
, notreplace
. The same rule applies if you try out examples at DotLiquid online. For more information, see Shopify Liquid filters and DotLiquid Liquid filters. The Shopify specification includes examples for each filter, so for comparison, you can try these examples at DotLiquid - Try online.The
json
filter from the Shopify extension filters is currently not implemented in DotLiquid. Typically, you can use this filter to prepare text output for JSON string parsing, but instead, you need to use theReplace
filter instead.The standard
Replace
filter in the DotLiquid implementation uses regular expression (RegEx) matching, while the Shopify implementation uses simple string matching. Both implementations appear to work the same way until you use a RegEx-reserved character or an escape character in the match parameter.For example, to escape the RegEx-reserved backslash (
\
) escape character, use| Replace: '\\', '\\'
, and not| Replace: '\', '\\'
. These examples show how theReplace
filter behaves differently when you try to escape the backslash character. While this version works successfully:{ "SampleText": "{{ 'The quick brown fox "jumped" over the sleeping dog\\' | Replace: '\\', '\\' | Replace: '"', '\"'}}"}
With this result:
{ "SampleText": "The quick brown fox \"jumped\" over the sleeping dog\\\\"}
This version fails:
{ "SampleText": "{{ 'The quick brown fox "jumped" over the sleeping dog\\' | Replace: '\', '\\' | Replace: '"', '\"'}}"}
With this error:
{ "SampleText": "Liquid error: parsing "\" - Illegal \ at end of pattern."}
For more information, see Replace standard filter uses RegEx pattern matching....
The
Sort
filter in the DotLiquid implementation sorts items in an array or collection by property but with these differences:Follows Shopify's sort_natural behavior, not Shopify's sort behavior.
Sorts only in string-alphanumeric order. For more information, see Numeric sort.
Uses case-insensitive order, not case-sensitive order. For more information, see Sort filter doesn't follow casing behavior from Shopify's specification.