mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
[CSV node] Add support for parsing empty strings and null values (#2510)
* [CSV node] Add support for parsing empty strings and null values * Add new lines at the end and fix script type. * Last one script type fix * Naming change
This commit is contained in:
parent
6912dec166
commit
91b7dd988e
@ -33,6 +33,10 @@
|
|||||||
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-hdrin"><label style="width:auto; margin-top:7px;" for="node-input-hdrin"><span data-i18n="csv.label.firstrow"></span></label><br/>
|
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-hdrin"><label style="width:auto; margin-top:7px;" for="node-input-hdrin"><span data-i18n="csv.label.firstrow"></span></label><br/>
|
||||||
<label> </label>
|
<label> </label>
|
||||||
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-strings"><label style="width:auto; margin-top:7px;" for="node-input-strings"><span data-i18n="csv.label.usestrings"></span></label><br/>
|
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-strings"><label style="width:auto; margin-top:7px;" for="node-input-strings"><span data-i18n="csv.label.usestrings"></span></label><br/>
|
||||||
|
<label> </label>
|
||||||
|
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-include_empty_strings"><label style="width:auto; margin-top:7px;" for="node-input-include_empty_strings"><span data-i18n="csv.label.include_empty_strings"></span></label><br/>
|
||||||
|
<label> </label>
|
||||||
|
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-include_null_values"><label style="width:auto; margin-top:7px;" for="node-input-include_null_values"><span data-i18n="csv.label.include_null_values"></span></label><br/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row" style="padding-left:20px;">
|
<div class="form-row" style="padding-left:20px;">
|
||||||
<label><i class="fa fa-sign-out"></i> <span data-i18n="csv.label.output"></span></label>
|
<label><i class="fa fa-sign-out"></i> <span data-i18n="csv.label.output"></span></label>
|
||||||
@ -74,7 +78,9 @@
|
|||||||
ret: {value:'\\n'},
|
ret: {value:'\\n'},
|
||||||
temp: {value:""},
|
temp: {value:""},
|
||||||
skip: {value:"0"},
|
skip: {value:"0"},
|
||||||
strings: {value:true}
|
strings: {value:true},
|
||||||
|
include_empty_strings: {value:""},
|
||||||
|
include_null_values: {value:""}
|
||||||
},
|
},
|
||||||
inputs:1,
|
inputs:1,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
|
@ -31,6 +31,8 @@ module.exports = function(RED) {
|
|||||||
this.skip = parseInt(n.skip || 0);
|
this.skip = parseInt(n.skip || 0);
|
||||||
this.store = [];
|
this.store = [];
|
||||||
this.parsestrings = n.strings;
|
this.parsestrings = n.strings;
|
||||||
|
this.include_empty_strings = n.include_empty_strings || false;
|
||||||
|
this.include_null_values = n.include_null_values || false;
|
||||||
if (this.parsestrings === undefined) { this.parsestrings = true; }
|
if (this.parsestrings === undefined) { this.parsestrings = true; }
|
||||||
var tmpwarn = true;
|
var tmpwarn = true;
|
||||||
var node = this;
|
var node = this;
|
||||||
@ -173,20 +175,29 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
else if ((line[i] === node.sep) && f) { // if it is the end of the line then finish
|
else if ((line[i] === node.sep) && f) { // if it is the end of the line then finish
|
||||||
if (!node.goodtmpl) { node.template[j] = "col"+(j+1); }
|
if (!node.goodtmpl) { node.template[j] = "col"+(j+1); }
|
||||||
if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "" ) ) {
|
if ( node.template[j] && (node.template[j] !== "") ) {
|
||||||
if ( (node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); }
|
// if no value between separators ('1,,"3"...') or if the line beings with separator (',1,"2"...') treat value as null
|
||||||
o[node.template[j]] = k[j];
|
if (line[i-1] === node.sep || line[i-1].includes('\n','\r')) k[j] = null;
|
||||||
|
if ( (k[j] !== null && node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); }
|
||||||
|
if (node.include_null_values && k[j] === null) o[node.template[j]] = k[j];
|
||||||
|
if (node.include_empty_strings && k[j] === "") o[node.template[j]] = k[j];
|
||||||
|
if (k[j] !== null && k[j] !== "") o[node.template[j]] = k[j];
|
||||||
}
|
}
|
||||||
j += 1;
|
j += 1;
|
||||||
k[j] = "";
|
// if separator is last char in processing string line (without end of line), add null value at the end - example: '1,2,3\n3,"3",'
|
||||||
|
k[j] = line.length - 1 === i ? null : "";
|
||||||
}
|
}
|
||||||
else if ((line[i] === "\n") || (line[i] === "\r")) { // handle multiple lines
|
else if ((line[i] === "\n") || (line[i] === "\r")) { // handle multiple lines
|
||||||
//console.log(j,k,o,k[j]);
|
//console.log(j,k,o,k[j]);
|
||||||
if (!node.goodtmpl) { node.template[j] = "col"+(j+1); }
|
if (!node.goodtmpl) { node.template[j] = "col"+(j+1); }
|
||||||
if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "") ) {
|
if ( node.template[j] && (node.template[j] !== "") ) {
|
||||||
if ( (node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); }
|
// if separator before end of line, set null value ie. '1,2,"3"\n1,2,\n1,2,3'
|
||||||
else { k[j].replace(/\r$/,''); }
|
if (line[i-1] === node.sep) k[j] = null;
|
||||||
o[node.template[j]] = k[j];
|
if ( (k[j] !== null && node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); }
|
||||||
|
else { if (k[j] !== null) k[j].replace(/\r$/,''); }
|
||||||
|
if (node.include_null_values && k[j] === null) o[node.template[j]] = k[j];
|
||||||
|
if (node.include_empty_strings && k[j] === "") o[node.template[j]] = k[j];
|
||||||
|
if (k[j] !== null && k[j] !== "") o[node.template[j]] = k[j];
|
||||||
}
|
}
|
||||||
if (JSON.stringify(o) !== "{}") { // don't send empty objects
|
if (JSON.stringify(o) !== "{}") { // don't send empty objects
|
||||||
a.push(o); // add to the array
|
a.push(o); // add to the array
|
||||||
@ -204,10 +215,13 @@ module.exports = function(RED) {
|
|||||||
// Finished so finalize and send anything left
|
// Finished so finalize and send anything left
|
||||||
//console.log(j,k,o,k[j]);
|
//console.log(j,k,o,k[j]);
|
||||||
if (!node.goodtmpl) { node.template[j] = "col"+(j+1); }
|
if (!node.goodtmpl) { node.template[j] = "col"+(j+1); }
|
||||||
if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "") ) {
|
|
||||||
if ( (node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); }
|
if ( node.template[j] && (node.template[j] !== "") ) {
|
||||||
else { k[j].replace(/\r$/,''); }
|
if ( (k[j] !== null && node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); }
|
||||||
o[node.template[j]] = k[j];
|
else { if (k[j] !== null) k[j].replace(/\r$/,''); }
|
||||||
|
if (node.include_null_values && k[j] === null) o[node.template[j]] = k[j];
|
||||||
|
if (node.include_empty_strings && k[j] === "") o[node.template[j]] = k[j];
|
||||||
|
if (k[j] !== null && k[j] !== "") o[node.template[j]] = k[j];
|
||||||
}
|
}
|
||||||
if (JSON.stringify(o) !== "{}") { // don't send empty objects
|
if (JSON.stringify(o) !== "{}") { // don't send empty objects
|
||||||
a.push(o); // add to the array
|
a.push(o); // add to the array
|
||||||
|
@ -698,7 +698,9 @@
|
|||||||
"output": "Output",
|
"output": "Output",
|
||||||
"includerow": "include column name row",
|
"includerow": "include column name row",
|
||||||
"newline": "Newline",
|
"newline": "Newline",
|
||||||
"usestrings": "parse numerical values"
|
"usestrings": "parse numerical values",
|
||||||
|
"include_empty_strings": "include empty strings",
|
||||||
|
"include_null_values": "include null values"
|
||||||
},
|
},
|
||||||
"placeholder": {
|
"placeholder": {
|
||||||
"columns": "comma-separated column names"
|
"columns": "comma-separated column names"
|
||||||
@ -894,7 +896,8 @@
|
|||||||
"fixup": "Fix-up exp"
|
"fixup": "Fix-up exp"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"invalid-expr": "Invalid JSONata expression: __error__"
|
"invalid-expr": "Invalid JSONata expression: __error__",
|
||||||
|
"invalid-type": "Cannot join __error__ to buffer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sort" : {
|
"sort" : {
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
will be used as the property names. Alternatively, the column names can be taken from the first row of the CSV.</p>
|
will be used as the property names. Alternatively, the column names can be taken from the first row of the CSV.</p>
|
||||||
<p>When converting to CSV, the column template is used to identify which properties to extract from the object and in what order.</p>
|
<p>When converting to CSV, the column template is used to identify which properties to extract from the object and in what order.</p>
|
||||||
<p>If the input is an array then the columns template is only used to optionally generate a row of column titles.</p>
|
<p>If the input is an array then the columns template is only used to optionally generate a row of column titles.</p>
|
||||||
|
<p>If 'parse numerical values' option is checked, string numerical values will be returned as numbers, ie. middle value '1,"1.5",2'.</p>
|
||||||
|
<p>If 'include empty strings' option is checked, empty strings will be returned in result, ie. middle value '"1","",3'.</p>
|
||||||
|
<p>If 'include null values' option is checked, null values will be returned in result, ie. middle value '"1",,3'.</p>
|
||||||
<p>The node can accept a multi-part input as long as the <code>parts</code> property is set correctly.</p>
|
<p>The node can accept a multi-part input as long as the <code>parts</code> property is set correctly.</p>
|
||||||
<p>If outputting multiple messages they will have their <code>parts</code> property set and form a complete message sequence.</p>
|
<p>If outputting multiple messages they will have their <code>parts</code> property set and form a complete message sequence.</p>
|
||||||
<p><b>Note:</b> the column template must be comma separated - even if a different separator is chosen for the data.</p>
|
<p><b>Note:</b> the column template must be comma separated - even if a different separator is chosen for the data.</p>
|
||||||
|
Loading…
Reference in New Issue
Block a user