Node-Red:通过属性值访问XML节点
Node-Red: access XML node by attribute value
我使用 Node-Red 来查询一个状态列表,它返回的时间和 XML 一样长。它基本上来自我的 Homematic 家庭自动化中央单元,即传感器值和状态。
现在我正在具体查询每个传感器,但也有一个功能可以一次获取所有内容,这对我来说看起来更经济,因为无论如何我都需要多个值。
但是,我不知道是否能保证这些值总是在同一个位置。
XML 看起来像这样:
在 Node-Red 调试中 window 我可以看到这样的结构:
我知道如何单独访问每个节点,但是如果我使用复制路径方法:
payload.state.device[0].channel[1].datapoint[0].$.value
如果中央单元中的 API 将来会更改顺序(也许如果我添加另一个/删除/重新连接传感器?),那最终会爆炸?
每个传感器都有自己的 ID,您可以看到
<device name="Fenster Bad" ise_id="3416" unreach="false" config_pending="false">
ise_id 设备节点中的属性。
现在问题:
我正在尝试访问以蓝色突出显示的值。
我可以使用不同的 ise_ids(高亮红色)到达那里。
但是我如何告诉节点 Red 不要通过索引走路径,而是通过属性 ise_id?
类似于:
payload.state.device['ise_id=3416'].channel[1].datapoint[0].$.value
但我在网上找不到任何明确地这样做的线程或教程...
请在此处查找示例 XML:
可能的解决方案:
xml节点会将XML文件转换为JavaScript对象。下面的节点,即配置有 jsonata
表达式的更改节点,将只过滤所需 ise_id
的数据,无论它在对象(或 xml)结构中的什么位置。
您可以在此 link 中了解有关 jsonata 的更多信息:https://docs.jsonata.org/overview
您可能需要专门阅读有关 Predicate queries
的页面:https://docs.jsonata.org/predicate
无论如何,我很乐意澄清任何问题。此外,您可以在 Node-RED forum
中找到大量 jsonata 示例(或提问)
Node-REd 流程:
[{"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":[]}]
过滤后的输出 ise_id = '3418'(例如):
我使用 Node-Red 来查询一个状态列表,它返回的时间和 XML 一样长。它基本上来自我的 Homematic 家庭自动化中央单元,即传感器值和状态。
现在我正在具体查询每个传感器,但也有一个功能可以一次获取所有内容,这对我来说看起来更经济,因为无论如何我都需要多个值。
但是,我不知道是否能保证这些值总是在同一个位置。
XML 看起来像这样:
在 Node-Red 调试中 window 我可以看到这样的结构:
我知道如何单独访问每个节点,但是如果我使用复制路径方法:
payload.state.device[0].channel[1].datapoint[0].$.value
如果中央单元中的 API 将来会更改顺序(也许如果我添加另一个/删除/重新连接传感器?),那最终会爆炸?
每个传感器都有自己的 ID,您可以看到
<device name="Fenster Bad" ise_id="3416" unreach="false" config_pending="false">
ise_id 设备节点中的属性。
现在问题:
我正在尝试访问以蓝色突出显示的值。 我可以使用不同的 ise_ids(高亮红色)到达那里。
但是我如何告诉节点 Red 不要通过索引走路径,而是通过属性 ise_id?
类似于:
payload.state.device['ise_id=3416'].channel[1].datapoint[0].$.value
但我在网上找不到任何明确地这样做的线程或教程...
请在此处查找示例 XML:
可能的解决方案:
xml节点会将XML文件转换为JavaScript对象。下面的节点,即配置有 jsonata
表达式的更改节点,将只过滤所需 ise_id
的数据,无论它在对象(或 xml)结构中的什么位置。
您可以在此 link 中了解有关 jsonata 的更多信息:https://docs.jsonata.org/overview
您可能需要专门阅读有关 Predicate queries
的页面:https://docs.jsonata.org/predicate
无论如何,我很乐意澄清任何问题。此外,您可以在 Node-RED forum
中找到大量 jsonata 示例(或提问)Node-REd 流程:
[{"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":[]}]
过滤后的输出 ise_id = '3418'(例如):