node-red-contrib-tak-registration 0.7.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/child_process.d.ts +5 -0
- package/node_modules/@types/node/dgram.d.ts +5 -0
- package/node_modules/@types/node/events.d.ts +35 -0
- package/node_modules/@types/node/fs/promises.d.ts +5 -0
- package/node_modules/@types/node/fs.d.ts +43 -5
- package/node_modules/@types/node/globals.d.ts +22 -0
- package/node_modules/@types/node/index.d.ts +1 -1
- package/node_modules/@types/node/inspector.d.ts +1 -1
- package/node_modules/@types/node/module.d.ts +103 -0
- package/node_modules/@types/node/net.d.ts +5 -0
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/stream.d.ts +143 -0
- package/node_modules/@types/node/test.d.ts +33 -4
- package/node_modules/@types/node/timers.d.ts +12 -2
- package/node_modules/@types/node/ts4.8/child_process.d.ts +5 -0
- package/node_modules/@types/node/ts4.8/dgram.d.ts +5 -0
- package/node_modules/@types/node/ts4.8/events.d.ts +35 -0
- package/node_modules/@types/node/ts4.8/fs/promises.d.ts +5 -0
- package/node_modules/@types/node/ts4.8/fs.d.ts +43 -5
- package/node_modules/@types/node/ts4.8/globals.d.ts +22 -0
- package/node_modules/@types/node/ts4.8/inspector.d.ts +1 -1
- package/node_modules/@types/node/ts4.8/module.d.ts +103 -0
- package/node_modules/@types/node/ts4.8/net.d.ts +5 -0
- package/node_modules/@types/node/ts4.8/stream.d.ts +762 -728
- package/node_modules/@types/node/ts4.8/test.d.ts +97 -50
- package/node_modules/@types/node/ts4.8/timers.d.ts +12 -2
- package/node_modules/@types/node/ts4.8/vm.d.ts +2 -1
- package/node_modules/@types/node/vm.d.ts +2 -1
- package/node_modules/axios/CHANGELOG.md +23 -0
- package/node_modules/axios/README.md +33 -5
- package/node_modules/axios/dist/axios.js +26 -18
- package/node_modules/axios/dist/axios.js.map +1 -1
- package/node_modules/axios/dist/axios.min.js +1 -1
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +24 -20
- package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
- package/node_modules/axios/dist/esm/axios.js +26 -21
- package/node_modules/axios/dist/esm/axios.js.map +1 -1
- package/node_modules/axios/dist/esm/axios.min.js +1 -1
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +27 -21
- package/node_modules/axios/dist/node/axios.cjs.map +1 -1
- package/node_modules/axios/index.d.cts +1 -0
- package/node_modules/axios/index.d.ts +3 -0
- package/node_modules/axios/index.js +2 -0
- package/node_modules/axios/lib/adapters/http.js +3 -1
- package/node_modules/axios/lib/axios.js +3 -0
- package/node_modules/axios/lib/core/Axios.js +2 -4
- package/node_modules/axios/lib/core/AxiosHeaders.js +11 -1
- package/node_modules/axios/lib/defaults/index.js +4 -11
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/utils.js +3 -2
- package/node_modules/axios/package.json +3 -1
- package/node_modules/fast-xml-parser/CHANGELOG.md +561 -0
- package/node_modules/fast-xml-parser/README.md +134 -287
- package/node_modules/fast-xml-parser/package.json +17 -40
- package/node_modules/fast-xml-parser/{cli.js → src/cli/cli.js} +16 -24
- package/node_modules/fast-xml-parser/src/cli/man.js +12 -0
- package/node_modules/fast-xml-parser/src/fxp.d.ts +108 -0
- package/node_modules/fast-xml-parser/src/fxp.js +11 -0
- package/node_modules/fast-xml-parser/src/util.js +0 -36
- package/node_modules/fast-xml-parser/src/validator.js +15 -5
- package/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js +269 -0
- package/node_modules/fast-xml-parser/src/xmlbuilder/orderedJs2Xml.js +131 -0
- package/node_modules/fast-xml-parser/src/xmlbuilder/prettifyJs2Xml.js +0 -0
- package/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js +152 -0
- package/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js +48 -0
- package/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js +589 -0
- package/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js +58 -0
- package/node_modules/fast-xml-parser/src/xmlparser/node2json.js +113 -0
- package/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js +25 -0
- package/node_modules/protobufjs/dist/light/protobuf.js +24 -13
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +12 -7
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +40 -18
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/package.json +1 -1
- package/node_modules/protobufjs/src/converter.js +2 -2
- package/node_modules/protobufjs/src/parse.js +4 -1
- package/node_modules/protobufjs/src/reader.js +8 -3
- package/node_modules/protobufjs/src/tokenize.js +2 -4
- package/package.json +4 -4
- package/tak-ingest.js +4 -3
- package/tak-registration.js +14 -5
- package/node_modules/fast-xml-parser/src/json2xml.js +0 -280
- package/node_modules/fast-xml-parser/src/nimndata.js +0 -144
- package/node_modules/fast-xml-parser/src/node2json.js +0 -42
- package/node_modules/fast-xml-parser/src/node2json_str.js +0 -63
- package/node_modules/fast-xml-parser/src/parser.d.ts +0 -79
- package/node_modules/fast-xml-parser/src/parser.js +0 -76
- package/node_modules/fast-xml-parser/src/xmlNode.js +0 -17
- package/node_modules/fast-xml-parser/src/xmlstr2xmlnode.js +0 -339
- /package/node_modules/fast-xml-parser/src/{read.js → cli/read.js} +0 -0
|
@@ -3,26 +3,19 @@
|
|
|
3
3
|
/*eslint-disable no-console*/
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
|
-
const
|
|
7
|
-
const readToEnd = require('./
|
|
6
|
+
const {XMLParser, XMLValidator} = require("../fxp");
|
|
7
|
+
const readToEnd = require('./read').readToEnd;
|
|
8
8
|
|
|
9
|
+
const version = require('./../../package.json').version;
|
|
9
10
|
if (process.argv[2] === '--help' || process.argv[2] === '-h') {
|
|
10
|
-
console.log(
|
|
11
|
-
console.log('----------------');
|
|
12
|
-
console.log('xml2js [-ns|-a|-c|-v|-V] <filename> [-o outputfile.json]');
|
|
13
|
-
console.log('cat xmlfile.xml | xml2js [-ns|-a|-c|-v|-V] [-o outputfile.json]');
|
|
14
|
-
console.log('-ns: remove namespace from tag and atrribute name.');
|
|
15
|
-
console.log("-a: don't parse attributes.");
|
|
16
|
-
console.log('-c: parse values to premitive type.');
|
|
17
|
-
console.log('-v: validate before parsing.');
|
|
18
|
-
console.log('-V: validate only.');
|
|
11
|
+
console.log(require("./man"));
|
|
19
12
|
} else if (process.argv[2] === '--version') {
|
|
20
|
-
console.log(
|
|
13
|
+
console.log(version);
|
|
21
14
|
} else {
|
|
22
15
|
const options = {
|
|
23
|
-
|
|
16
|
+
removeNSPrefix: true,
|
|
24
17
|
ignoreAttributes: false,
|
|
25
|
-
|
|
18
|
+
parseTagValue: true,
|
|
26
19
|
parseAttributeValue: true,
|
|
27
20
|
};
|
|
28
21
|
let fileName = '';
|
|
@@ -31,11 +24,11 @@ if (process.argv[2] === '--help' || process.argv[2] === '-h') {
|
|
|
31
24
|
let validateOnly = false;
|
|
32
25
|
for (let i = 2; i < process.argv.length; i++) {
|
|
33
26
|
if (process.argv[i] === '-ns') {
|
|
34
|
-
options.
|
|
27
|
+
options.removeNSPrefix = false;
|
|
35
28
|
} else if (process.argv[i] === '-a') {
|
|
36
29
|
options.ignoreAttributes = true;
|
|
37
30
|
} else if (process.argv[i] === '-c') {
|
|
38
|
-
options.
|
|
31
|
+
options.parseTagValue = false;
|
|
39
32
|
options.parseAttributeValue = false;
|
|
40
33
|
} else if (process.argv[i] === '-o') {
|
|
41
34
|
outputFileName = process.argv[++i];
|
|
@@ -48,20 +41,18 @@ if (process.argv[2] === '--help' || process.argv[2] === '-h') {
|
|
|
48
41
|
fileName = process.argv[i];
|
|
49
42
|
}
|
|
50
43
|
}
|
|
44
|
+
|
|
51
45
|
const callback = function(xmlData) {
|
|
52
46
|
let output = '';
|
|
53
47
|
if (validate) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
output = JSON.stringify(parser.parse(xmlData, options), null, 4);
|
|
57
|
-
} else {
|
|
58
|
-
output = result;
|
|
59
|
-
}
|
|
48
|
+
const parser = new XMLParser(options);
|
|
49
|
+
output = parser.parse(xmlData,validate);
|
|
60
50
|
} else if (validateOnly) {
|
|
61
|
-
output =
|
|
51
|
+
output = XMLValidator.validate(xmlData);
|
|
62
52
|
process.exitCode = output === true ? 0 : 1;
|
|
63
53
|
} else {
|
|
64
|
-
|
|
54
|
+
const parser = new XMLParser(options);
|
|
55
|
+
output = JSON.stringify(parser.parse(xmlData,validate), null, 4);
|
|
65
56
|
}
|
|
66
57
|
if (outputFileName) {
|
|
67
58
|
writeToFile(outputFileName, output);
|
|
@@ -71,6 +62,7 @@ if (process.argv[2] === '--help' || process.argv[2] === '-h') {
|
|
|
71
62
|
};
|
|
72
63
|
|
|
73
64
|
try {
|
|
65
|
+
|
|
74
66
|
if (!fileName) {
|
|
75
67
|
readToEnd(process.stdin, function(err, data) {
|
|
76
68
|
if (err) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module.exports = `Fast XML Parser 4.0.0
|
|
2
|
+
----------------
|
|
3
|
+
$ fxparser [-ns|-a|-c|-v|-V] <filename> [-o outputfile.json]
|
|
4
|
+
$ cat xmlfile.xml | fxparser [-ns|-a|-c|-v|-V] [-o outputfile.json]
|
|
5
|
+
|
|
6
|
+
Options
|
|
7
|
+
----------------
|
|
8
|
+
-ns: remove namespace from tag and atrribute name.
|
|
9
|
+
-a: don't parse attributes.
|
|
10
|
+
-c: parse values to premitive type.
|
|
11
|
+
-v: validate before parsing.
|
|
12
|
+
-V: validate only.`
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
type X2jOptions = {
|
|
2
|
+
preserveOrder: boolean;
|
|
3
|
+
attributeNamePrefix: string;
|
|
4
|
+
attributesGroupName: false | string;
|
|
5
|
+
textNodeName: string;
|
|
6
|
+
ignoreAttributes: boolean;
|
|
7
|
+
removeNSPrefix: boolean;
|
|
8
|
+
allowBooleanAttributes: boolean;
|
|
9
|
+
parseTagValue: boolean;
|
|
10
|
+
parseAttributeValue: boolean;
|
|
11
|
+
trimValues: boolean;
|
|
12
|
+
cdataPropName: false | string;
|
|
13
|
+
commentPropName: false | string;
|
|
14
|
+
/**
|
|
15
|
+
Control how tag value should be parsed. Called only if tag value is not empty
|
|
16
|
+
|
|
17
|
+
@returns {undefined|null} `undefined` or `null` to set original value.
|
|
18
|
+
@returns {unknown}
|
|
19
|
+
1. Different value or value with different data type to set new value. <br>
|
|
20
|
+
2. Same value to set parsed value if `parseTagValue: true`.
|
|
21
|
+
*/
|
|
22
|
+
tagValueProcessor: (tagName: string, tagValue: string, jPath: string, hasAttributes: boolean, isLeafNode: boolean) => unknown;
|
|
23
|
+
attributeValueProcessor: (attrName: string, attrValue: string, jPath: string) => unknown;
|
|
24
|
+
numberParseOptions: strnumOptions;
|
|
25
|
+
stopNodes: string[];
|
|
26
|
+
unpairedTags: string[];
|
|
27
|
+
alwaysCreateTextNode: boolean;
|
|
28
|
+
isArray: (tagName: string, jPath: string, isLeafNode: boolean, isAttribute: boolean) => boolean;
|
|
29
|
+
processEntities: boolean;
|
|
30
|
+
htmlEntities: boolean;
|
|
31
|
+
ignoreDeclaration: boolean;
|
|
32
|
+
ignorePiTags: boolean;
|
|
33
|
+
transformTagName: ((tagName: string) => string) | false;
|
|
34
|
+
transformAttributeName: ((attributeName: string) => string) | false;
|
|
35
|
+
/**
|
|
36
|
+
Change the tag name when a different name is returned. Skip the tag from parsed result when false is returned.
|
|
37
|
+
Modify `attrs` object to control attributes for the given tag.
|
|
38
|
+
|
|
39
|
+
@returns {string} new tag name.
|
|
40
|
+
@returns false to skip the tag
|
|
41
|
+
*/
|
|
42
|
+
updateTag: (tagName: string, jPath: string, attrs: {[k: string]: string}) => string | boolean;
|
|
43
|
+
};
|
|
44
|
+
type strnumOptions = {
|
|
45
|
+
hex: boolean;
|
|
46
|
+
leadingZeros: boolean,
|
|
47
|
+
skipLike?: RegExp,
|
|
48
|
+
eNotation?: boolean
|
|
49
|
+
}
|
|
50
|
+
type X2jOptionsOptional = Partial<X2jOptions>;
|
|
51
|
+
type validationOptions = {
|
|
52
|
+
allowBooleanAttributes: boolean;
|
|
53
|
+
unpairedTags: string[];
|
|
54
|
+
};
|
|
55
|
+
type validationOptionsOptional = Partial<validationOptions>;
|
|
56
|
+
|
|
57
|
+
type XmlBuilderOptions = {
|
|
58
|
+
attributeNamePrefix: string;
|
|
59
|
+
attributesGroupName: false | string;
|
|
60
|
+
textNodeName: string;
|
|
61
|
+
ignoreAttributes: boolean;
|
|
62
|
+
cdataPropName: false | string;
|
|
63
|
+
commentPropName: false | string;
|
|
64
|
+
format: boolean;
|
|
65
|
+
indentBy: string;
|
|
66
|
+
arrayNodeName: string;
|
|
67
|
+
suppressEmptyNode: boolean;
|
|
68
|
+
suppressUnpairedNode: boolean;
|
|
69
|
+
suppressBooleanAttributes: boolean;
|
|
70
|
+
preserveOrder: boolean;
|
|
71
|
+
unpairedTags: string[];
|
|
72
|
+
stopNodes: string[];
|
|
73
|
+
tagValueProcessor: (name: string, value: unknown) => string;
|
|
74
|
+
attributeValueProcessor: (name: string, value: unknown) => string;
|
|
75
|
+
processEntities: boolean;
|
|
76
|
+
oneListGroup: boolean;
|
|
77
|
+
};
|
|
78
|
+
type XmlBuilderOptionsOptional = Partial<XmlBuilderOptions>;
|
|
79
|
+
|
|
80
|
+
type ESchema = string | object | Array<string|object>;
|
|
81
|
+
|
|
82
|
+
type ValidationError = {
|
|
83
|
+
err: {
|
|
84
|
+
code: string;
|
|
85
|
+
msg: string,
|
|
86
|
+
line: number,
|
|
87
|
+
col: number
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export class XMLParser {
|
|
92
|
+
constructor(options?: X2jOptionsOptional);
|
|
93
|
+
parse(xmlData: string | Buffer ,validationOptions?: validationOptionsOptional | boolean): any;
|
|
94
|
+
/**
|
|
95
|
+
* Add Entity which is not by default supported by this library
|
|
96
|
+
* @param entityIndentifier {string} Eg: 'ent' for &ent;
|
|
97
|
+
* @param entityValue {string} Eg: '\r'
|
|
98
|
+
*/
|
|
99
|
+
addEntity(entityIndentifier: string, entityValue: string): void;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export class XMLValidator{
|
|
103
|
+
static validate( xmlData: string, options?: validationOptionsOptional): true | ValidationError;
|
|
104
|
+
}
|
|
105
|
+
export class XMLBuilder {
|
|
106
|
+
constructor(options?: XmlBuilderOptionsOptional);
|
|
107
|
+
build(jObj: any): any;
|
|
108
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const validator = require('./validator');
|
|
4
|
+
const XMLParser = require('./xmlparser/XMLParser');
|
|
5
|
+
const XMLBuilder = require('./xmlbuilder/json2xml');
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
XMLParser: XMLParser,
|
|
9
|
+
XMLValidator: validator,
|
|
10
|
+
XMLBuilder: XMLBuilder
|
|
11
|
+
}
|
|
@@ -67,42 +67,6 @@ exports.getValue = function(v) {
|
|
|
67
67
|
// const fakeCall = function(a) {return a;};
|
|
68
68
|
// const fakeCallNoReturn = function() {};
|
|
69
69
|
|
|
70
|
-
exports.buildOptions = function(options, defaultOptions, props) {
|
|
71
|
-
let newOptions = {};
|
|
72
|
-
if (!options) {
|
|
73
|
-
return defaultOptions; //if there are not options
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
for (let i = 0; i < props.length; i++) {
|
|
77
|
-
if (options[props[i]] !== undefined) {
|
|
78
|
-
newOptions[props[i]] = options[props[i]];
|
|
79
|
-
} else {
|
|
80
|
-
newOptions[props[i]] = defaultOptions[props[i]];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return newOptions;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Check if a tag name should be treated as array
|
|
88
|
-
*
|
|
89
|
-
* @param tagName the node tagname
|
|
90
|
-
* @param arrayMode the array mode option
|
|
91
|
-
* @param parentTagName the parent tag name
|
|
92
|
-
* @returns {boolean} true if node should be parsed as array
|
|
93
|
-
*/
|
|
94
|
-
exports.isTagNameInArrayMode = function (tagName, arrayMode, parentTagName) {
|
|
95
|
-
if (arrayMode === false) {
|
|
96
|
-
return false;
|
|
97
|
-
} else if (arrayMode instanceof RegExp) {
|
|
98
|
-
return arrayMode.test(tagName);
|
|
99
|
-
} else if (typeof arrayMode === 'function') {
|
|
100
|
-
return !!arrayMode(tagName, parentTagName);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return arrayMode === "strict";
|
|
104
|
-
}
|
|
105
|
-
|
|
106
70
|
exports.isName = isName;
|
|
107
71
|
exports.getAllMatches = getAllMatches;
|
|
108
72
|
exports.nameRegexp = nameRegexp;
|
|
@@ -4,13 +4,12 @@ const util = require('./util');
|
|
|
4
4
|
|
|
5
5
|
const defaultOptions = {
|
|
6
6
|
allowBooleanAttributes: false, //A tag can have attributes without any value
|
|
7
|
+
unpairedTags: []
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
const props = ['allowBooleanAttributes'];
|
|
10
|
-
|
|
11
10
|
//const tagsPattern = new RegExp("<\\/?([\\w:\\-_\.]+)\\s*\/?>","g");
|
|
12
11
|
exports.validate = function (xmlData, options) {
|
|
13
|
-
options =
|
|
12
|
+
options = Object.assign({}, defaultOptions, options);
|
|
14
13
|
|
|
15
14
|
//xmlData = xmlData.replace(/(\r\n|\n|\r)/gm,"");//make it single line
|
|
16
15
|
//xmlData = xmlData.replace(/(^\s*<\?xml.*?\?>)/g,"");//Remove XML starting tag
|
|
@@ -25,7 +24,7 @@ exports.validate = function (xmlData, options) {
|
|
|
25
24
|
// check for byte order mark (BOM)
|
|
26
25
|
xmlData = xmlData.substr(1);
|
|
27
26
|
}
|
|
28
|
-
|
|
27
|
+
|
|
29
28
|
for (let i = 0; i < xmlData.length; i++) {
|
|
30
29
|
|
|
31
30
|
if (xmlData[i] === '<' && xmlData[i+1] === '?') {
|
|
@@ -130,6 +129,8 @@ exports.validate = function (xmlData, options) {
|
|
|
130
129
|
//if the root level has been reached before ...
|
|
131
130
|
if (reachedRoot === true) {
|
|
132
131
|
return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));
|
|
132
|
+
} else if(options.unpairedTags.indexOf(tagName) !== -1){
|
|
133
|
+
//don't push into stack
|
|
133
134
|
} else {
|
|
134
135
|
tags.push({tagName, tagStartPos});
|
|
135
136
|
}
|
|
@@ -156,6 +157,10 @@ exports.validate = function (xmlData, options) {
|
|
|
156
157
|
if (afterAmp == -1)
|
|
157
158
|
return getErrorObject('InvalidChar', "char '&' is not expected.", getLineNumberForPosition(xmlData, i));
|
|
158
159
|
i = afterAmp;
|
|
160
|
+
}else{
|
|
161
|
+
if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {
|
|
162
|
+
return getErrorObject('InvalidXml', "Extra text at the end", getLineNumberForPosition(xmlData, i));
|
|
163
|
+
}
|
|
159
164
|
}
|
|
160
165
|
} //end of reading tag text value
|
|
161
166
|
if (xmlData[i] === '<') {
|
|
@@ -163,7 +168,7 @@ exports.validate = function (xmlData, options) {
|
|
|
163
168
|
}
|
|
164
169
|
}
|
|
165
170
|
} else {
|
|
166
|
-
if (
|
|
171
|
+
if ( isWhiteSpace(xmlData[i])) {
|
|
167
172
|
continue;
|
|
168
173
|
}
|
|
169
174
|
return getErrorObject('InvalidChar', "char '"+xmlData[i]+"' is not expected.", getLineNumberForPosition(xmlData, i));
|
|
@@ -183,6 +188,9 @@ exports.validate = function (xmlData, options) {
|
|
|
183
188
|
return true;
|
|
184
189
|
};
|
|
185
190
|
|
|
191
|
+
function isWhiteSpace(char){
|
|
192
|
+
return char === ' ' || char === '\t' || char === '\n' || char === '\r';
|
|
193
|
+
}
|
|
186
194
|
/**
|
|
187
195
|
* Read Processing insstructions and skip
|
|
188
196
|
* @param {*} xmlData
|
|
@@ -318,6 +326,8 @@ function validateAttributeString(attrStr, options) {
|
|
|
318
326
|
if (matches[i][1].length === 0) {
|
|
319
327
|
//nospace before attribute name: a="sd"b="saf"
|
|
320
328
|
return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' has no space in starting.", getPositionFromMatch(matches[i]))
|
|
329
|
+
} else if (matches[i][3] !== undefined && matches[i][4] === undefined) {
|
|
330
|
+
return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' is without value.", getPositionFromMatch(matches[i]));
|
|
321
331
|
} else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {
|
|
322
332
|
//independent attribute: ab
|
|
323
333
|
return getErrorObject('InvalidAttr', "boolean attribute '"+matches[i][2]+"' is not allowed.", getPositionFromMatch(matches[i]));
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
//parse Empty Node as self closing node
|
|
3
|
+
const buildFromOrderedJs = require('./orderedJs2Xml');
|
|
4
|
+
|
|
5
|
+
const defaultOptions = {
|
|
6
|
+
attributeNamePrefix: '@_',
|
|
7
|
+
attributesGroupName: false,
|
|
8
|
+
textNodeName: '#text',
|
|
9
|
+
ignoreAttributes: true,
|
|
10
|
+
cdataPropName: false,
|
|
11
|
+
format: false,
|
|
12
|
+
indentBy: ' ',
|
|
13
|
+
suppressEmptyNode: false,
|
|
14
|
+
suppressUnpairedNode: true,
|
|
15
|
+
suppressBooleanAttributes: true,
|
|
16
|
+
tagValueProcessor: function(key, a) {
|
|
17
|
+
return a;
|
|
18
|
+
},
|
|
19
|
+
attributeValueProcessor: function(attrName, a) {
|
|
20
|
+
return a;
|
|
21
|
+
},
|
|
22
|
+
preserveOrder: false,
|
|
23
|
+
commentPropName: false,
|
|
24
|
+
unpairedTags: [],
|
|
25
|
+
entities: [
|
|
26
|
+
{ regex: new RegExp("&", "g"), val: "&" },//it must be on top
|
|
27
|
+
{ regex: new RegExp(">", "g"), val: ">" },
|
|
28
|
+
{ regex: new RegExp("<", "g"), val: "<" },
|
|
29
|
+
{ regex: new RegExp("\'", "g"), val: "'" },
|
|
30
|
+
{ regex: new RegExp("\"", "g"), val: """ }
|
|
31
|
+
],
|
|
32
|
+
processEntities: true,
|
|
33
|
+
stopNodes: [],
|
|
34
|
+
// transformTagName: false,
|
|
35
|
+
// transformAttributeName: false,
|
|
36
|
+
oneListGroup: false
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function Builder(options) {
|
|
40
|
+
this.options = Object.assign({}, defaultOptions, options);
|
|
41
|
+
if (this.options.ignoreAttributes || this.options.attributesGroupName) {
|
|
42
|
+
this.isAttribute = function(/*a*/) {
|
|
43
|
+
return false;
|
|
44
|
+
};
|
|
45
|
+
} else {
|
|
46
|
+
this.attrPrefixLen = this.options.attributeNamePrefix.length;
|
|
47
|
+
this.isAttribute = isAttribute;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.processTextOrObjNode = processTextOrObjNode
|
|
51
|
+
|
|
52
|
+
if (this.options.format) {
|
|
53
|
+
this.indentate = indentate;
|
|
54
|
+
this.tagEndChar = '>\n';
|
|
55
|
+
this.newLine = '\n';
|
|
56
|
+
} else {
|
|
57
|
+
this.indentate = function() {
|
|
58
|
+
return '';
|
|
59
|
+
};
|
|
60
|
+
this.tagEndChar = '>';
|
|
61
|
+
this.newLine = '';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Builder.prototype.build = function(jObj) {
|
|
66
|
+
if(this.options.preserveOrder){
|
|
67
|
+
return buildFromOrderedJs(jObj, this.options);
|
|
68
|
+
}else {
|
|
69
|
+
if(Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1){
|
|
70
|
+
jObj = {
|
|
71
|
+
[this.options.arrayNodeName] : jObj
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return this.j2x(jObj, 0).val;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
Builder.prototype.j2x = function(jObj, level) {
|
|
79
|
+
let attrStr = '';
|
|
80
|
+
let val = '';
|
|
81
|
+
for (let key in jObj) {
|
|
82
|
+
if (typeof jObj[key] === 'undefined') {
|
|
83
|
+
// supress undefined node only if it is not an attribute
|
|
84
|
+
if (this.isAttribute(key)) {
|
|
85
|
+
val += '';
|
|
86
|
+
}
|
|
87
|
+
} else if (jObj[key] === null) {
|
|
88
|
+
// null attribute should be ignored by the attribute list, but should not cause the tag closing
|
|
89
|
+
if (this.isAttribute(key)) {
|
|
90
|
+
val += '';
|
|
91
|
+
} else if (key[0] === '?') {
|
|
92
|
+
val += this.indentate(level) + '<' + key + '?' + this.tagEndChar;
|
|
93
|
+
} else {
|
|
94
|
+
val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;
|
|
95
|
+
}
|
|
96
|
+
// val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;
|
|
97
|
+
} else if (jObj[key] instanceof Date) {
|
|
98
|
+
val += this.buildTextValNode(jObj[key], key, '', level);
|
|
99
|
+
} else if (typeof jObj[key] !== 'object') {
|
|
100
|
+
//premitive type
|
|
101
|
+
const attr = this.isAttribute(key);
|
|
102
|
+
if (attr) {
|
|
103
|
+
attrStr += this.buildAttrPairStr(attr, '' + jObj[key]);
|
|
104
|
+
}else {
|
|
105
|
+
//tag value
|
|
106
|
+
if (key === this.options.textNodeName) {
|
|
107
|
+
let newval = this.options.tagValueProcessor(key, '' + jObj[key]);
|
|
108
|
+
val += this.replaceEntitiesValue(newval);
|
|
109
|
+
} else {
|
|
110
|
+
val += this.buildTextValNode(jObj[key], key, '', level);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} else if (Array.isArray(jObj[key])) {
|
|
114
|
+
//repeated nodes
|
|
115
|
+
const arrLen = jObj[key].length;
|
|
116
|
+
let listTagVal = "";
|
|
117
|
+
for (let j = 0; j < arrLen; j++) {
|
|
118
|
+
const item = jObj[key][j];
|
|
119
|
+
if (typeof item === 'undefined') {
|
|
120
|
+
// supress undefined node
|
|
121
|
+
} else if (item === null) {
|
|
122
|
+
if(key[0] === "?") val += this.indentate(level) + '<' + key + '?' + this.tagEndChar;
|
|
123
|
+
else val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;
|
|
124
|
+
// val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;
|
|
125
|
+
} else if (typeof item === 'object') {
|
|
126
|
+
if(this.options.oneListGroup ){
|
|
127
|
+
listTagVal += this.j2x(item, level + 1).val;
|
|
128
|
+
}else{
|
|
129
|
+
listTagVal += this.processTextOrObjNode(item, key, level)
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
listTagVal += this.buildTextValNode(item, key, '', level);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if(this.options.oneListGroup){
|
|
136
|
+
listTagVal = this.buildObjectNode(listTagVal, key, '', level);
|
|
137
|
+
}
|
|
138
|
+
val += listTagVal;
|
|
139
|
+
} else {
|
|
140
|
+
//nested node
|
|
141
|
+
if (this.options.attributesGroupName && key === this.options.attributesGroupName) {
|
|
142
|
+
const Ks = Object.keys(jObj[key]);
|
|
143
|
+
const L = Ks.length;
|
|
144
|
+
for (let j = 0; j < L; j++) {
|
|
145
|
+
attrStr += this.buildAttrPairStr(Ks[j], '' + jObj[key][Ks[j]]);
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
val += this.processTextOrObjNode(jObj[key], key, level)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return {attrStr: attrStr, val: val};
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
Builder.prototype.buildAttrPairStr = function(attrName, val){
|
|
156
|
+
val = this.options.attributeValueProcessor(attrName, '' + val);
|
|
157
|
+
val = this.replaceEntitiesValue(val);
|
|
158
|
+
if (this.options.suppressBooleanAttributes && val === "true") {
|
|
159
|
+
return ' ' + attrName;
|
|
160
|
+
} else return ' ' + attrName + '="' + val + '"';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function processTextOrObjNode (object, key, level) {
|
|
164
|
+
const result = this.j2x(object, level + 1);
|
|
165
|
+
if (object[this.options.textNodeName] !== undefined && Object.keys(object).length === 1) {
|
|
166
|
+
return this.buildTextValNode(object[this.options.textNodeName], key, result.attrStr, level);
|
|
167
|
+
} else {
|
|
168
|
+
return this.buildObjectNode(result.val, key, result.attrStr, level);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
Builder.prototype.buildObjectNode = function(val, key, attrStr, level) {
|
|
173
|
+
if(val === ""){
|
|
174
|
+
if(key[0] === "?") return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar;
|
|
175
|
+
else {
|
|
176
|
+
return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;
|
|
177
|
+
}
|
|
178
|
+
}else{
|
|
179
|
+
|
|
180
|
+
let tagEndExp = '</' + key + this.tagEndChar;
|
|
181
|
+
let piClosingChar = "";
|
|
182
|
+
|
|
183
|
+
if(key[0] === "?") {
|
|
184
|
+
piClosingChar = "?";
|
|
185
|
+
tagEndExp = "";
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// attrStr is an empty string in case the attribute came as undefined or null
|
|
189
|
+
if ((attrStr || attrStr === '') && val.indexOf('<') === -1) {
|
|
190
|
+
return ( this.indentate(level) + '<' + key + attrStr + piClosingChar + '>' + val + tagEndExp );
|
|
191
|
+
} else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) {
|
|
192
|
+
return this.indentate(level) + `<!--${val}-->` + this.newLine;
|
|
193
|
+
}else {
|
|
194
|
+
return (
|
|
195
|
+
this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar +
|
|
196
|
+
val +
|
|
197
|
+
this.indentate(level) + tagEndExp );
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
Builder.prototype.closeTag = function(key){
|
|
203
|
+
let closeTag = "";
|
|
204
|
+
if(this.options.unpairedTags.indexOf(key) !== -1){ //unpaired
|
|
205
|
+
if(!this.options.suppressUnpairedNode) closeTag = "/"
|
|
206
|
+
}else if(this.options.suppressEmptyNode){ //empty
|
|
207
|
+
closeTag = "/";
|
|
208
|
+
}else{
|
|
209
|
+
closeTag = `></${key}`
|
|
210
|
+
}
|
|
211
|
+
return closeTag;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function buildEmptyObjNode(val, key, attrStr, level) {
|
|
215
|
+
if (val !== '') {
|
|
216
|
+
return this.buildObjectNode(val, key, attrStr, level);
|
|
217
|
+
} else {
|
|
218
|
+
if(key[0] === "?") return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar;
|
|
219
|
+
else {
|
|
220
|
+
return this.indentate(level) + '<' + key + attrStr + '/' + this.tagEndChar;
|
|
221
|
+
// return this.buildTagStr(level,key, attrStr);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
Builder.prototype.buildTextValNode = function(val, key, attrStr, level) {
|
|
227
|
+
if (this.options.cdataPropName !== false && key === this.options.cdataPropName) {
|
|
228
|
+
return this.indentate(level) + `<![CDATA[${val}]]>` + this.newLine;
|
|
229
|
+
}else if (this.options.commentPropName !== false && key === this.options.commentPropName) {
|
|
230
|
+
return this.indentate(level) + `<!--${val}-->` + this.newLine;
|
|
231
|
+
}else if(key[0] === "?") {//PI tag
|
|
232
|
+
return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar;
|
|
233
|
+
}else{
|
|
234
|
+
let textValue = this.options.tagValueProcessor(key, val);
|
|
235
|
+
textValue = this.replaceEntitiesValue(textValue);
|
|
236
|
+
|
|
237
|
+
if( textValue === ''){
|
|
238
|
+
return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;
|
|
239
|
+
}else{
|
|
240
|
+
return this.indentate(level) + '<' + key + attrStr + '>' +
|
|
241
|
+
textValue +
|
|
242
|
+
'</' + key + this.tagEndChar;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
Builder.prototype.replaceEntitiesValue = function(textValue){
|
|
248
|
+
if(textValue && textValue.length > 0 && this.options.processEntities){
|
|
249
|
+
for (let i=0; i<this.options.entities.length; i++) {
|
|
250
|
+
const entity = this.options.entities[i];
|
|
251
|
+
textValue = textValue.replace(entity.regex, entity.val);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return textValue;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function indentate(level) {
|
|
258
|
+
return this.options.indentBy.repeat(level);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function isAttribute(name /*, options*/) {
|
|
262
|
+
if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) {
|
|
263
|
+
return name.substr(this.attrPrefixLen);
|
|
264
|
+
} else {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
module.exports = Builder;
|