Logic app jsonpath expression to update sub-child node based on another sub-child value

64 views Asked by At

I have an XML in logic app like below:

<JournalCollection>
    <Journal>
        <ChangeCode>
            <Code>a1</Code>
        </ChangeCode>
    </Journal>
    <Journal>
        <ChangeCode>
            <Code>b1</Code>
        </ChangeCode>
        <Description>Description</Description>
    </Journal>
    <Journal>
        <ChangeCode>
            <Code>c1</Code>
        </ChangeCode>
    </Journal>
</JournalCollection>

I need to add "Description" field only for the Code = b1. I have the position of that in a variable but I am not able to use json path expression as I see this is not supported in logic apps:

enter image description here

Adding a variable in json path expression to set the position value throws this error:

enter image description here

I also tried using transform XML shape but since I need to check the position of a child element in the destination schema, I am not able to update it.

Is there any way we can update an XML for a sub-child node based on another sub-child node value in logic apps?

3

There are 3 answers

1
gregsdennis On

JSON Path isn't supported natively in Java (or any language that I'm aware of). You'll need a JSON Path processor, like Jayway. You'll likely need to give the library the path as a string, then it will parse the path and give you the result you're looking for.

I'm not sure how you would go about including external libs in the context of an Azure Logic App, though.

2
Skin On

You could use the C# Script Execute operation in the Advanced Data Operations connector.

https://statesolutions.com.au/c-script-execute/

It's like the JavaScript operation but obviously it uses C# and the experience is a little different.

This is the script ...

// Load the XML into an XmlDocument
var xmlDoc = new System.Xml.XmlDocument();
xmlDoc.LoadXml(parameters.xml);

// Find the <Journal> elements
System.Xml.XmlNodeList journalNodes = xmlDoc.SelectNodes("//Journal");

// Loop through each <Journal> element
foreach (System.Xml.XmlNode journalNode in journalNodes)
{
    // Find the <ChangeCode> element
    var changeCodeNode = journalNode.SelectSingleNode("ChangeCode");

    // Find the <Code> element under <ChangeCode>
    var codeNode = changeCodeNode.SelectSingleNode("Code");

    // Check if the value of <Code> is "b1"
    if (codeNode.InnerText == "b1")
    {
        // Create a new <Description> element
        var descriptionElement = xmlDoc.CreateElement("Description");
        descriptionElement.InnerText = "Description";

        // Insert the <Description> element as a sibling to <ChangeCode>
        journalNode.InsertAfter(descriptionElement, changeCodeNode);
    }
}

// Display the modified XML
return xmlDoc.OuterXml;

... and along with this, I created a variable called XML that stores your XML payload without the <Description> element. I then pass that value into the Parameters of the C# Script Execute operation ...

{
  "xml": @{variables('XML')}
}

... and this is an example of what it looks like when configured to run ...

Operation

Result

As you can see, the return value gives you the XML (as a string) that you're after ...

{
  "returnValue": "<JournalCollection><Journal><ChangeCode><Code>a1</Code></ChangeCode></Journal><Journal><ChangeCode><Code>b1</Code></ChangeCode><Description>Description</Description></Journal><Journal><ChangeCode><Code>c1</Code></ChangeCode></Journal></JournalCollection>",
  "log": []
}

Naturally, the script could be changed to be more generic/forgiving if need be, it's quite targeted but this is a very valid approach.

enter image description here

0
viktorh On

If I understood you correctly, i think this is doable with both xpath or converting it to json, parsing and converting back to XML