Extract a value from message payload using Name not Object

Can anyone guide me. I am trying to extract the value associated with a string.
The data is coming from an XML file, of which, I have no control over its format.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE data [
 <!ELEMENT data       (parameter+)>
 <!ELEMENT parameter  (name,value)>
 <!ELEMENT name       (#PCDATA)>
 <!ELEMENT value      (#PCDATA)>
]>
<data>
   <parameter>
   	<name>DB_L2174_ALARMS</name>
   	<value><![CDATA[0000000000000111000000000000000]]></value>
   </parameter>
   <parameter>
   	<name>DB_DEMOD_LICENCE_OPTIONS</name>
   	<value><![CDATA[1110010000000000000001000000000000000000]]></value>
   </parameter>
   <parameter>
   	<name>DB_DECOD_LICENCE_OPTIONS</name>
   	<value><![CDATA[0000000000000000000000000000000000000000]]></value>
   </parameter>
   <parameter>
   	<name>DB_DEMOD_SELFTEST_RESULTS</name>
   	<value><![CDATA[100000000000000000000000000000000]]></value>
   </parameter>
   <parameter>
   	<name>DB_L2174_RX_MODE</name>
   	<value><![CDATA[DVBT]]></value>
   </parameter>
   <parameter>
   	<name>DB_L2174_FREQ1</name>
   	<value><![CDATA[2.030000]]></value>
   </parameter>
   <parameter>
   	<name>DB_DEMOD_MOD_TYPE</name>
...

I am using a JSON node to convert it to a JSON object, which gives it the following format;

25/08/2022, 11:17:44node: debug 3
msg.payload : Object
object
data: object
parameter: array[247]
[0 … 9]
0: object
name: array[1]
value: array[1]
1: object
name: array[1]
0: "DB_DEMOD_LICENCE_OPTIONS"
value: array[1]
0: "1110010000000000000001000000000000000000"
2: object
name: array[1]
0: "DB_DECOD_LICENCE_OPTIONS"
value: array[1]
0: "0000000000000000000000000000000000000000"
3: object
name: array[1]
0: "DB_DEMOD_SELFTEST_RESULTS"
value: array[1]
0: "100000000000000000000000000000000"
4: object
name: array[1]
value: array[1]
5: object
6: object
7: object
8: object
9: object
[10 … 19]
[20 … 29]
[30 … 39]
[40 … 49]
[50 … 59]
[60 … 69]
[70 … 79]
[80 … 89]
[90 … 99]
[100 … 109]
[110 … 119]
[120 … 129]
[130 … 139]
[140 … 149]
[150 … 159]
[160 … 169]
[170 … 179]
[180 … 189]
[190 … 199]
[200 … 209]
[210 … 219]
[220 … 229]
[230 … 239]
[240 … 246]

I can extract any of the 247 values I want by using the code;

'msg.payload = msg.payload.data.parameter[34].value'
'return msg;'

But the problem I need to overcome is the fact that the particular 'names and values' I want to extract are not always in the same numbered objects. So for example, what is in object 112, is sometimes in object 111 or 113 or sometimes is not there at all.

Therefore what I would like to able to do, is search the payload by “name” and then from that, extract the associated “value” of that particular array. I have seen similar questions but I can’t find any examples on how to do it.

you can use JSONata or Javascript find().
e.g.

[{"id":"88aeec8c.8e386","type":"inject","z":"9a86d59e88442f2c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"<?xml version=\"1.0\" encoding=\"utf-8\" ?> <!DOCTYPE data [  <!ELEMENT data       (parameter+)>  <!ELEMENT parameter  (name,value)>  <!ELEMENT name       (#PCDATA)>  <!ELEMENT value      (#PCDATA)> ]> <data>    <parameter>    \t<name>DB_L2174_ALARMS</name>    \t<value><![CDATA[0000000000000111000000000000000]]></value>    </parameter>    <parameter>    \t<name>DB_DEMOD_LICENCE_OPTIONS</name>    \t<value><![CDATA[1110010000000000000001000000000000000000]]></value>    </parameter>    <parameter>    \t<name>DB_DECOD_LICENCE_OPTIONS</name>    \t<value><![CDATA[0000000000000000000000000000000000000000]]></value>    </parameter>    <parameter>    \t<name>DB_DEMOD_SELFTEST_RESULTS</name>    \t<value><![CDATA[100000000000000000000000000000000]]></value>    </parameter>    <parameter>    \t<name>DB_L2174_RX_MODE</name>    \t<value><![CDATA[DVBT]]></value>    </parameter>    <parameter>    \t<name>DB_L2174_FREQ1</name>    \t<value><![CDATA[2.030000]]></value>    </parameter>    </data>","payloadType":"str","x":100,"y":320,"wires":[["642c8fe4.aa6928"]]},{"id":"642c8fe4.aa6928","type":"xml","z":"9a86d59e88442f2c","name":"","property":"payload","attr":"","chr":"","x":260,"y":320,"wires":[["c82abad0.d79e28","df71d57e.fe9248"]]},{"id":"c82abad0.d79e28","type":"change","z":"9a86d59e88442f2c","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$$.payload.data.parameter[name[0]=\"DB_L2174_ALARMS\"].value[0]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":320,"wires":[["9e47108c.90d0f8"]]},{"id":"df71d57e.fe9248","type":"function","z":"9a86d59e88442f2c","name":"","func":"msg.payload = msg.payload.data.parameter.find(obj => obj.name[0] === \"DB_L2174_ALARMS\").value[0]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":360,"wires":[["9e47108c.90d0f8"]]},{"id":"9e47108c.90d0f8","type":"debug","z":"9a86d59e88442f2c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":360,"wires":[]}]

Javascript

msg.payload = msg.payload.data.parameter.find(obj => obj.name[0] === "DB_L2174_ALARMS").value[0]
return msg;

Jsonata

$$.payload.data.parameter[name[0] = "DB_L2174_ALARMS"].value[0]

Thank you, that is exactly what I wanted.
Also, thank you for providing examples pertinent to my particular JSON format.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.