假设我有以下CSV文件:
A_Key;B_Key;C_Key;...;X_Key
Value 1;2;Value 1.3;...;Value 1.24
Value 1;;Value 2.3;...;Value 2.24
...
我已经创建了一个节点红色模板,该模板允许我提取一些键值对以创建简单的JSON输出。但是,这是一对一的关系,但是我需要一个更灵活的解决方案。对于应该产生输出的对象有一些要求:
上面的CSV生成的对象看起来像这样:
[
{
"A_Key": "Value 1",
"C_Key": "Value 1.3",
"Properties": {
"B_Key": "2",
"F_Key": ...,
...
"X_Key": "Value 1.24"
},
"Extras": {
"D_Key": ...,
"E_Key": ...,
...
}
},
{
"A_Key": "Value 1",
"C_Key": "Value 2.3",
"Properties": {
"B_Key": "NULL",
"F_Key": ...,
...
"X_Key": "Value 2.24"
},
"Extras": {
"D_Key": ...,
...
}
},
]
我想执行以下操作:我想在Node Red中构建一个功能节点“ Prepare JSON”,该节点遍历CSV的列并将列标题用作生成的JSON的键。我已经在流程的开头准备了一个设置所需变量的函数:
var primaryKey = "C_Key";
var mandatoryPart = "Properties";
var mandatoryKeys = ["B_Key",
"F_Key",
...
"X_Key"];
var optionalPart = "Extras";
var appendOptionalPart = true;
msg.primaryKey = primaryKey;
msg.mandatoryPart = mandatoryPart
msg.mandatoryKeys = mandatoryKeys;
msg.optionalPart = optionalPart;
msg.appendOptionalPart = appendOptionalPart;
我尝试了几种方法来运行“准备JSON”功能:
msg.payload = {
"A_Key": "Value 1",
"C_Key": msg.payload.C_Key,
"Properties": {
"B_Key": msg.payload.B_Key
},
optionalPart: msg.optionalPart
}
//for(var i =0; i<msg.mandatoryParts.length;i++)
//{
// msg.payload.Properties.push(msg.payload[msg.mandatoryKeys[i]].value);
// msg.payload.Properties.push(msg.mandatoryKeys[i]);
//}
return msg;
顶部的静态部分工作正常,但是,如何动态设置元素键的名称呢?看一下“ optionalPart”行:变量是“ msg.optionalPart”,但是当我尝试直接访问它时,Node Red抱怨该点。我尝试将其用转义引号引起来,但Node Red也不喜欢该行开头的反斜杠字符。我还尝试了字符串连接,当然,如果我将变量名放在引号中,则将其原样打印在输出中...
底部的注释部分是我第一次尝试遍历元素,我也被困在这里。非常感谢您的帮助!
这是当前流程的图像:
答案 0 :(得分:0)
这可以通过JSONata轻松完成,JSONata是一种简化数据转换的语言。
Node-RED流的主要部分将是具有以下JSONata表达式的变更节点:
payload.{"A_Key" :A_Key, "C_Key" :C_Key, "Properties" : {"B_Key" :B_Key, "F_Key" :F_Key, "X_Key" :X_Key}, "Extras" : {"D_Key" :D_Key, "E_Key" :E_Key }}
这是要为您的Node-RED导入的流程,只需修复文件名路径:
[{"id":"52781b93.a86794","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"fc475896.7f6a68","type":"csv","z":"52781b93.a86794","name":"","sep":",","hdrin":true,"hdrout":"","multi":"mult","ret":"\\n","temp":"","skip":"0","x":430,"y":260,"wires":[["c6f562e7.6189c"]]},{"id":"282d5fcd.692cb","type":"debug","z":"52781b93.a86794","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":770,"y":260,"wires":[]},{"id":"22fa22d.c2868de","type":"inject","z":"52781b93.a86794","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":260,"wires":[["93544cf8.57fad"]]},{"id":"93544cf8.57fad","type":"file in","z":"52781b93.a86794","name":"Read CSV","filename":"f1.csv","format":"utf8","chunk":false,"sendError":false,"x":280,"y":260,"wires":[["fc475896.7f6a68"]]},{"id":"c6f562e7.6189c","type":"change","z":"52781b93.a86794","name":"Prepare JSON","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.{\"A_Key\" :A_Key, \"C_Key\" :C_Key, \"Properties\" : {\"B_Key\" :B_Key, \"F_Key\" :F_Key, \"X_Key\" :X_Key}, \"Extras\" : {\"D_Key\" :D_Key, \"E_Key\" :E_Key }}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":260,"wires":[["282d5fcd.692cb"]]}]
编辑:为您有关动态元素键的问题添加一个可能的答案。
如果我正确理解,您想向msg.payload
添加可变的密钥。为此,您可以使用Javascript Computed Property Names。
在您的功能节点中,将是这样的:
msg.payload = {
"A_Key": "Value 1",
"C_Key": msg.payload.C_Key,
"Properties": {
"B_Key": msg.payload.B_Key
},
//optionalPart: msg.optionalPart
[optionalPart]:["Z_Key"]
// or [msg.optionalPart]:["Z_Key"] if more appropriate for your logic
}
您将在msg.payload
中添加属性键“ Extras”。
作为旁注(由于这不是您的OP的一部分),请注意,如果msg.payload.C_Key
和msg.payload.B_Key
的初始化不正确,代码下面的内容尚不清楚,并且可能会引起麻烦。
"C_Key": msg.payload.C_Key,
"B_Key": msg.payload.B_Key,