aslmx
aslmx

Reputation: 23

Node-Red: access XML node by attribute value

I use Node-Red to query a status list that comes back as long XML. It is basically from my Homematic home automation central unit, i.e. sensor values and status.

right now I'm querying each sensor specifically, but there is also a function to get everything at once, which looks more economically to me, as I need multiple values anyway.

However, I don't know if it is guaranteed that the values will always be at the same position.

The XML looks like this:

XML provided by central unit

In Node-Red debug window I can see the structure like this:

XML in Node Red

I know how to access each of the nodes individually, but if I use the copy Path method:

payload.state.device[0].channel[1].datapoint[0].$.value

That will eventually blow up, if the API in the central unit will change the order in the future (maybe if I add another / remove / reconnect a Sensor?)

Each Sensor has its own ID, which you can see as

<device name="Fenster Bad" ise_id="3416" unreach="false" config_pending="false">

ise_id attribute in a device node.

Now the question:

I'm trying to access the value highlighted in blue. I could use different ise_ids (highlighed red) to get there.

XML and highlighted what I want

But how do I tell node Red to not go down a path by index, but rather by the attribute ise_id?

Something like:

payload.state.device['ise_id=3416'].channel[1].datapoint[0].$.value

But I can't find any thread or tutorial on the net who explicitly does exactly that...

Please find example XML here:

https://pastebin.com/ic4eDXpp

Upvotes: 0

Views: 1730

Answers (1)

AIOT MAKER
AIOT MAKER

Reputation: 584

A possible solution:

enter image description here

The xml node will convert the XML file into a JavaScript object. The following node, that is a change node configured with a jsonata expression will filter only the data for the desired ise_id, no matter where it is in the object (or xml) structure.

You can learn more about jsonata in this link: https://docs.jsonata.org/overview

You may want to read specifically the page about Predicate queries: https://docs.jsonata.org/predicate

Anyway, I would be glad to clarify any question. Additionally, you can find plenty of examples of jsonata (or ask questions) in Node-RED forum

Node-REd Flow:

[{"id":"d4dde310.a8375","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"968c62d.36b67a","type":"inject","z":"d4dde310.a8375","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":120,"wires":[["37118c19.2fd204"]]},{"id":"37118c19.2fd204","type":"file in","z":"d4dde310.a8375","name":"Read XML file","filename":"C:\\Users\\OCM\\.node-red\\static\\nrfiles\\s1.xml","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":340,"y":120,"wires":[["a493ccb.367ae3"]]},{"id":"76cd1e5e.a132f","type":"debug","z":"d4dde310.a8375","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"filter","targetType":"msg","x":780,"y":120,"wires":[]},{"id":"a493ccb.367ae3","type":"xml","z":"d4dde310.a8375","name":"","property":"payload","attr":"","chr":"","x":490,"y":120,"wires":[["70d00d31.6dd424","e7614ac8.183a78"]]},{"id":"70d00d31.6dd424","type":"change","z":"d4dde310.a8375","name":"","rules":[{"t":"set","p":"filter","pt":"msg","to":"payload.**[ise_id = '3418']","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":120,"wires":[["76cd1e5e.a132f"]]},{"id":"e7614ac8.183a78","type":"debug","z":"d4dde310.a8375","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":630,"y":200,"wires":[]}]

Output when filtered ise_id = '3418' (for instance):

enter image description here

Upvotes: 1

Related Questions