Receive XML from webhook (without converting to JSON with normalized tags)

The idea is:

When a webhook receives XML data it automatically converts it to JSON and normalizes the tags. I need to have a way to get directly the XML (or JSON which isn’t normalized).

My use case:

Steps to reproduce the behavior:

  1. Add a webhook node
  2. Send to it the following XML:
<soapenv:Envelope>
	<FooBar>
		<Bar/>
	<FooBar>
</soapenv:Envelope>
  1. See the received body:
"soapenv:envelope": {
	"foobar": {
		"bar": ""
	}
}

I want to to 1) get the XML like string or 2) get the tags unnormalized like:

"soapenv:Envelope": {
	"FooBar": {
		"Bar": ""
	}
}

I think it would be beneficial to add this because:

This way all capital letters are lost and the tags differ from other data I use. The tags cannot be unnormalized.

Are you willing to work on this?

Yes, I can work on this.

By the time the data hits the webhook node, it’s already parsed by the body-parse-xml middleware. This middleware by default parses all the keys in the XML to lowercase.

Right off the top of my head. I would:

  1. Add the verify handler to the XML middleware, and inject the XML without modifications in the rawBody property.
  2. In the webhook node, you now can use the rawData options to add the XML without modifications to the binary data This will allow you to see the XML in the output’s binary tab.

  1. Parse the binary data (the XML base64 encoded) to a string. You can do that with a function node and the code below. Ideally, you would not have to use the function node but the Move Binary Data node. Sadly, it currently only moves data from Binary to JSON. However, adding Binary to XML should be really simple.
const data = items[0].binary.data.data;
return {
  rawXml: Buffer.from(data, 'base64').toString()
}

NOTE: Step 3 will only work if step 1 is merged.

XML used for testing
<breakfast_menu>
    <food>
        <name>Belgian Waffles</name>
        <price>$5.95</price>
        <description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
        <calories>650</calories>
    </food>
    <food>
        <name>Strawberry Belgian Waffles</name>
        <price>$7.95</price>
        <description>Light Belgian waffles covered with strawberries and whipped cream</description>
        <calories>900</calories>
    </food>
    <food>
        <name>Berry-Berry Belgian Waffles</name>
        <price>$8.95</price>
        <description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
        <calories>900</calories>
    </food>
    <food>
        <name>French Toast</name>
        <price>$4.50</price>
        <description>Thick slices made from our homemade sourdough bread</description>
        <calories>600</calories>
    </food>
    <food>
        <name>Homestyle Breakfast</name>
        <price>$6.95</price>
        <description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
        <calories>950</calories>
    </food>
</breakfast_menu>
1 Like

When you create a feature request, please also upvote it.

Thank you, I will look into it next week.

Got added. Once is merged, you should be able to use the function node as in the example above.

1 Like

Got released with [email protected]

1 Like

Responding a bit late, but thank you a lot for adding this!

To add to the thread, in case anyone is creating a trigger node and wants to get the XML response as JSON with non normalized properties, instead of:

const bodyData = this.getBodyData();

I was able to get it like:

const req = this.getRequestObject();
// @ts-ignore
const rawXml = req.rawBody;
const bodyData = await convertXmlToJson(rawXml);
3 Likes