xml-toolkit 1.0.43 → 1.0.45
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 +30 -4
- package/badges/coverage-branches.svg +1 -0
- package/badges/coverage-functions.svg +1 -0
- package/badges/coverage-jest coverage.svg +1 -0
- package/badges/coverage-lines.svg +1 -0
- package/badges/coverage-statements.svg +1 -0
- package/index.js +17 -0
- package/lib/AttributesMap.js +62 -21
- package/lib/EntityResolver.js +0 -2
- package/lib/MoxyLikeJsonEncoder.js +13 -17
- package/lib/NamespacePrefixesMap.js +11 -15
- package/lib/NamespacesMap.js +0 -6
- package/lib/SAXEvent.js +12 -55
- package/lib/SOAP11.js +10 -34
- package/lib/SOAP12.js +1 -1
- package/lib/SOAPEncoding.js +4 -3
- package/lib/XMLIterator.js +1 -1
- package/lib/XMLLexer.js +12 -19
- package/lib/XMLMarshaller.js +45 -243
- package/lib/XMLNode.js +41 -57
- package/lib/XMLParser.js +2 -3
- package/lib/XMLPrinter.js +9 -3
- package/lib/XMLReader.js +2 -14
- package/lib/XMLSchema.js +54 -52
- package/lib/XMLSchemaBuiltIn.js +29 -0
- package/lib/XMLSchemaXml.js +24 -0
- package/lib/XMLSchemata.js +84 -120
- package/lib/XSSimpleType.js +327 -0
- package/lib/soap-1.2.xsd +1 -3
- package/lib/xml.xsd +38 -0
- package/lib/xsd.xsd +57 -0
- package/package.json +2 -2
package/lib/XMLLexer.js
CHANGED
|
@@ -14,11 +14,10 @@ const CH_MINUS = '-'.charCodeAt (0)
|
|
|
14
14
|
const CH_SQUARE = '['.charCodeAt (0)
|
|
15
15
|
const CH_GT = '>'.charCodeAt (0)
|
|
16
16
|
|
|
17
|
-
const CL_DEAFULT =
|
|
18
|
-
const CL_PI =
|
|
19
|
-
const CL_COMMENT =
|
|
20
|
-
const CL_SQ_1 =
|
|
21
|
-
const CL_SQ_2 = Buffer.from (']]', 'ascii')
|
|
17
|
+
const CL_DEAFULT = ''
|
|
18
|
+
const CL_PI = '?'
|
|
19
|
+
const CL_COMMENT = '--'
|
|
20
|
+
const CL_SQ_1 = ']'
|
|
22
21
|
|
|
23
22
|
const S_ENCODING = Symbol ('encoding')
|
|
24
23
|
|
|
@@ -54,13 +53,11 @@ const XMLLexer = class extends Transform {
|
|
|
54
53
|
|
|
55
54
|
isClosing (pos) {
|
|
56
55
|
|
|
57
|
-
const {awaited} = this, {length} = awaited; if (length === 0) return true
|
|
56
|
+
const {awaited, body} = this, {length} = awaited; if (length === 0) return true
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
const from = pos - length; if (from < this.start) return false
|
|
60
59
|
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
if (length === 2 && this.body.charCodeAt (from + 1) !== awaited [1]) return false
|
|
60
|
+
for (let i = 0; i < length; i ++) if (body.charCodeAt (from + i) !== awaited.charCodeAt (i)) return false
|
|
64
61
|
|
|
65
62
|
return true
|
|
66
63
|
|
|
@@ -114,7 +111,7 @@ const XMLLexer = class extends Transform {
|
|
|
114
111
|
|
|
115
112
|
}
|
|
116
113
|
|
|
117
|
-
}
|
|
114
|
+
}
|
|
118
115
|
|
|
119
116
|
break
|
|
120
117
|
|
|
@@ -149,7 +146,7 @@ const XMLLexer = class extends Transform {
|
|
|
149
146
|
{
|
|
150
147
|
|
|
151
148
|
const pos = start + 2; if (pos >= body.length) return null
|
|
152
|
-
|
|
149
|
+
|
|
153
150
|
switch (body.charCodeAt (pos)) {
|
|
154
151
|
|
|
155
152
|
case CH_MINUS:
|
|
@@ -186,7 +183,7 @@ const XMLLexer = class extends Transform {
|
|
|
186
183
|
case ST_TAG_X:
|
|
187
184
|
|
|
188
185
|
for (let pos = this.position + 1; pos < body.length; pos ++) {
|
|
189
|
-
|
|
186
|
+
|
|
190
187
|
switch (body.charCodeAt (pos)) {
|
|
191
188
|
|
|
192
189
|
case CH_SQUARE:
|
|
@@ -197,10 +194,6 @@ const XMLLexer = class extends Transform {
|
|
|
197
194
|
this.awaited = CL_SQ_1
|
|
198
195
|
break
|
|
199
196
|
|
|
200
|
-
case CL_SQ_1:
|
|
201
|
-
this.awaited = CL_SQ_2
|
|
202
|
-
break
|
|
203
|
-
|
|
204
197
|
}
|
|
205
198
|
|
|
206
199
|
this.position = pos
|
|
@@ -249,7 +242,7 @@ const XMLLexer = class extends Transform {
|
|
|
249
242
|
|
|
250
243
|
let {beforeBody, start} = this
|
|
251
244
|
|
|
252
|
-
return
|
|
245
|
+
return beforeBody + BigInt (start)
|
|
253
246
|
|
|
254
247
|
}
|
|
255
248
|
|
|
@@ -265,7 +258,7 @@ const XMLLexer = class extends Transform {
|
|
|
265
258
|
|
|
266
259
|
}
|
|
267
260
|
|
|
268
|
-
_transform (chunk,
|
|
261
|
+
_transform (chunk, _, callback) {
|
|
269
262
|
|
|
270
263
|
if (Buffer.isBuffer (chunk)) chunk = this.decoder.write (chunk)
|
|
271
264
|
|
package/lib/XMLMarshaller.js
CHANGED
|
@@ -1,56 +1,10 @@
|
|
|
1
1
|
const assert = require ('assert')
|
|
2
|
-
const stringEscape = require ('string-escape-map')
|
|
3
2
|
const NamespacePrefixesMap = require ('./NamespacePrefixesMap.js')
|
|
4
|
-
|
|
5
|
-
let esc = [
|
|
6
|
-
['<', '<'],
|
|
7
|
-
['>', '>'],
|
|
8
|
-
['&', '&'],
|
|
9
|
-
['"', '"']
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
//const XML_BODY = new stringEscape (esc)
|
|
13
|
-
|
|
14
|
-
//esc.push (['"', '"'])
|
|
15
|
-
|
|
16
|
-
const XML_ATTR = new stringEscape (esc)
|
|
17
|
-
|
|
18
|
-
const BOOL = new Map ([
|
|
19
|
-
['0', 'false'],
|
|
20
|
-
['false', 'false'],
|
|
21
|
-
['N', 'false'],
|
|
22
|
-
['1', 'true'],
|
|
23
|
-
['true', 'true'],
|
|
24
|
-
['Y', 'true'],
|
|
25
|
-
])
|
|
26
|
-
|
|
27
|
-
const XML_DECL = [
|
|
28
|
-
['version', '1.0'],
|
|
29
|
-
['encoding', null],
|
|
30
|
-
['standalone', null]
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
const _declaration = o => {
|
|
34
|
-
|
|
35
|
-
if (typeof o !== 'object' || o === null) return ''
|
|
36
|
-
|
|
37
|
-
let s = '<?xml'
|
|
38
|
-
|
|
39
|
-
for (const [name, def] of XML_DECL) {
|
|
40
|
-
|
|
41
|
-
const f = name in o; if (!f && def === null) continue
|
|
42
|
-
|
|
43
|
-
s += ' ' + name + '="' + (f ? o [name] : def) + '"'
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return s + '?>'
|
|
48
|
-
|
|
49
|
-
}
|
|
3
|
+
const XMLPrinter = require ('./XMLPrinter.js')
|
|
50
4
|
|
|
51
5
|
const XMLMarshaller = class {
|
|
52
6
|
|
|
53
|
-
constructor (xs, localName, namespaceURI) {
|
|
7
|
+
constructor (xs, localName, namespaceURI, printerOptions = {}) {
|
|
54
8
|
|
|
55
9
|
this.xs = xs
|
|
56
10
|
|
|
@@ -62,25 +16,29 @@ const XMLMarshaller = class {
|
|
|
62
16
|
|
|
63
17
|
this.isNsDumped = false
|
|
64
18
|
|
|
65
|
-
this.
|
|
19
|
+
this.printer = new XMLPrinter (printerOptions)
|
|
66
20
|
|
|
67
21
|
}
|
|
68
22
|
|
|
69
23
|
stringify (data, o = {}) {
|
|
70
24
|
|
|
71
|
-
const {schemaElement} = this, {targetNamespace, attributes
|
|
25
|
+
const {schemaElement, printer} = this, {targetNamespace, attributes} = schemaElement
|
|
72
26
|
|
|
73
27
|
if (typeof o === 'string') o = {localName: o}
|
|
74
28
|
|
|
75
|
-
|
|
29
|
+
{
|
|
30
|
+
|
|
31
|
+
const {declaration} = o
|
|
76
32
|
|
|
77
|
-
|
|
33
|
+
if (declaration) printer.decl = declaration
|
|
78
34
|
|
|
79
|
-
|
|
35
|
+
}
|
|
80
36
|
|
|
81
|
-
|
|
37
|
+
printer.reset ()
|
|
82
38
|
|
|
83
|
-
|
|
39
|
+
this.appendElement (schemaElement, data, this.ns.QName (o.localName || attributes.name, targetNamespace))
|
|
40
|
+
|
|
41
|
+
return printer.text
|
|
84
42
|
|
|
85
43
|
}
|
|
86
44
|
|
|
@@ -90,68 +48,41 @@ const XMLMarshaller = class {
|
|
|
90
48
|
|
|
91
49
|
this.appendElementBody (node, data)
|
|
92
50
|
|
|
93
|
-
this.
|
|
51
|
+
this.printer.closeElement ()
|
|
94
52
|
|
|
95
53
|
}
|
|
96
54
|
|
|
97
55
|
appendStartTag (node, data, qName) {
|
|
98
|
-
|
|
99
|
-
this.
|
|
100
|
-
|
|
101
|
-
this.buf += '<' + qName
|
|
102
|
-
|
|
56
|
+
|
|
57
|
+
this.printer.openElement (qName)
|
|
58
|
+
|
|
103
59
|
if (!this.isNsDumped) {
|
|
104
60
|
|
|
105
|
-
this.
|
|
61
|
+
this.printer.text += this.ns
|
|
106
62
|
|
|
107
63
|
this.isNsDumped = true
|
|
108
64
|
|
|
109
65
|
}
|
|
110
66
|
|
|
111
|
-
const {type} = node.attributes; if (type) this.appendAttributes (this.xs.getType (type), data)
|
|
112
|
-
|
|
113
67
|
this.appendAttributes (node, data)
|
|
114
68
|
|
|
115
|
-
this.buf += '>'
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
appendEndTag () {
|
|
120
|
-
|
|
121
|
-
this.buf += '</' + this.qNames.pop () + '>'
|
|
122
|
-
|
|
123
69
|
}
|
|
124
70
|
|
|
125
71
|
appendNullElement (node) {
|
|
126
72
|
|
|
127
73
|
const {attributes: {name, nillable}, targetNamespace} = node
|
|
128
74
|
|
|
129
|
-
if (
|
|
75
|
+
if (nillable !== 'true' && nillable !== '1') return
|
|
130
76
|
|
|
131
77
|
const qName = this.ns.QName (name, targetNamespace)
|
|
132
78
|
|
|
133
|
-
this.
|
|
79
|
+
this.printer
|
|
80
|
+
.openElement (qName)
|
|
81
|
+
.writeAttribute ('xsi:nil', 'true')
|
|
82
|
+
.closeElement ()
|
|
134
83
|
|
|
135
84
|
}
|
|
136
85
|
|
|
137
|
-
appendScalar (node, data, restriction = {}) {
|
|
138
|
-
|
|
139
|
-
for (const {localName, attributes, children} of node.children) {
|
|
140
|
-
|
|
141
|
-
if (localName === 'restriction') {
|
|
142
|
-
|
|
143
|
-
for (const {localName, attributes: {value}} of children) restriction [localName] = value
|
|
144
|
-
|
|
145
|
-
return this.appendScalar (this.xs.getType (attributes.base), data, restriction)
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
this.buf += this.to_string (data, node.attributes.name, restriction)
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
155
86
|
appendElementBody (node, data) {
|
|
156
87
|
|
|
157
88
|
const {attributes: {type}, children} = node
|
|
@@ -164,65 +95,33 @@ const XMLMarshaller = class {
|
|
|
164
95
|
|
|
165
96
|
appendAttributes (node, data) {
|
|
166
97
|
|
|
167
|
-
const {localName,
|
|
98
|
+
const {localName, attributes, children, targetNamespace} = node, {name, ref} = attributes
|
|
168
99
|
|
|
169
100
|
if (ref) return this.appendAttributes (this.xs.getByReference (ref), data)
|
|
101
|
+
|
|
102
|
+
const {type} = node.attributes; if (type) this.appendAttributes (this.xs.getType (type), data)
|
|
170
103
|
|
|
171
104
|
switch (localName) {
|
|
172
|
-
|
|
173
|
-
case 'anyAttribute':
|
|
174
|
-
|
|
175
|
-
if (data == null || typeof data !== 'object') return
|
|
176
|
-
|
|
177
|
-
if (null in data)
|
|
178
|
-
|
|
179
|
-
for (const o of Object.values (data [null]))
|
|
180
|
-
|
|
181
|
-
for (const [k, v] of Object.entries (o))
|
|
182
|
-
|
|
183
|
-
this.buf += ' ' + k + '="' + XML_ATTR.escape ('' + v) + '"'
|
|
184
|
-
|
|
185
|
-
break
|
|
186
105
|
|
|
187
|
-
case 'attribute':
|
|
188
|
-
|
|
189
|
-
if (data == null || typeof data !== 'object') return
|
|
190
|
-
|
|
191
|
-
if (!(name in data)) return
|
|
192
|
-
|
|
193
|
-
let v = data [name]; if (v == null) return
|
|
194
|
-
|
|
195
|
-
this.buf += ' ' + this.ns.QName (name, targetNamespace) + '="'
|
|
196
|
-
|
|
197
|
-
if (type) {
|
|
198
|
-
|
|
199
|
-
this.appendScalar (this.xs.getType (type), v)
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
|
|
204
|
-
for (const child of node.children) if (child.localName === 'simpleType') this.appendScalar (child, v)
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
this.buf += '"'
|
|
209
|
-
|
|
210
|
-
break
|
|
211
|
-
|
|
212
|
-
case 'any':
|
|
213
106
|
case 'sequence':
|
|
214
107
|
case 'choice':
|
|
215
108
|
case 'group':
|
|
216
|
-
case 'simpleType':
|
|
217
|
-
|
|
109
|
+
case 'simpleType':
|
|
218
110
|
return
|
|
219
111
|
|
|
220
|
-
case '
|
|
221
|
-
|
|
112
|
+
case 'attribute':
|
|
113
|
+
|
|
114
|
+
const v = data [name]; if (v == null) return
|
|
115
|
+
|
|
116
|
+
return this.printer.writeAttribute (
|
|
117
|
+
this.ns.QName (name, targetNamespace),
|
|
118
|
+
this.xs.getAttributeSimpleType (node).stringify (v)
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
case 'extension':
|
|
222
122
|
this.appendAttributes (this.xs.getType (attributes.base), data)
|
|
223
123
|
|
|
224
124
|
default:
|
|
225
|
-
|
|
226
125
|
for (const i of children) this.appendAttributes (i, data)
|
|
227
126
|
|
|
228
127
|
}
|
|
@@ -231,7 +130,7 @@ const XMLMarshaller = class {
|
|
|
231
130
|
|
|
232
131
|
appendContent (node, data) {
|
|
233
132
|
|
|
234
|
-
const {localName,
|
|
133
|
+
const {localName, attributes, children, targetNamespace} = node, {name, ref} = attributes
|
|
235
134
|
|
|
236
135
|
if (localName === 'attribute') return
|
|
237
136
|
|
|
@@ -241,16 +140,20 @@ const XMLMarshaller = class {
|
|
|
241
140
|
|
|
242
141
|
case 'any':
|
|
243
142
|
|
|
244
|
-
if (null in data) for (const xml in data [null]) this.
|
|
143
|
+
if (null in data) for (const xml in data [null]) this.printer.writeBody (xml)
|
|
245
144
|
|
|
246
145
|
return
|
|
247
146
|
|
|
248
147
|
case 'simpleType':
|
|
249
148
|
|
|
250
|
-
if (
|
|
149
|
+
if (typeof data === 'object' && data.hasOwnProperty (null)) data = data [null]
|
|
150
|
+
|
|
151
|
+
const type = this.xs.getSimpleType (node)
|
|
251
152
|
|
|
252
|
-
|
|
153
|
+
const xml = type.stringify (data)
|
|
253
154
|
|
|
155
|
+
this.printer.writeCharacters (xml)
|
|
156
|
+
|
|
254
157
|
return
|
|
255
158
|
|
|
256
159
|
case 'element':
|
|
@@ -278,108 +181,7 @@ const XMLMarshaller = class {
|
|
|
278
181
|
}
|
|
279
182
|
|
|
280
183
|
}
|
|
281
|
-
|
|
282
|
-
to_string (v, type, restriction = {}) {
|
|
283
|
-
|
|
284
|
-
const carp = () => {throw new Error (`Invalid value for ${type} type: ${v} (${typeof v})`)}
|
|
285
|
-
|
|
286
|
-
switch (type) {
|
|
287
184
|
|
|
288
|
-
case 'boolean':
|
|
289
|
-
if (BOOL.has (v)) return BOOL.get (v)
|
|
290
|
-
return !v ? 'false' : 'true'
|
|
291
|
-
|
|
292
|
-
case 'date':
|
|
293
|
-
switch (typeof v) {
|
|
294
|
-
case 'string':
|
|
295
|
-
if (v.length === 10) return v
|
|
296
|
-
case 'number':
|
|
297
|
-
case 'bigint':
|
|
298
|
-
const d = new Date (v)
|
|
299
|
-
if (isNaN (d)) carp ()
|
|
300
|
-
v = d
|
|
301
|
-
}
|
|
302
|
-
if (v instanceof Date) {
|
|
303
|
-
return v.toJSON ().slice (0, 10)
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
carp ()
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
case 'dateTime':
|
|
310
|
-
switch (typeof v) {
|
|
311
|
-
case 'string':
|
|
312
|
-
if (v.length === 10) return v + 'T00:00:00'
|
|
313
|
-
return v
|
|
314
|
-
case 'number':
|
|
315
|
-
case 'bigint':
|
|
316
|
-
v = new Date (v)
|
|
317
|
-
}
|
|
318
|
-
if (v instanceof Date) {
|
|
319
|
-
return v.toJSON ()
|
|
320
|
-
}
|
|
321
|
-
else {
|
|
322
|
-
carp ()
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
case 'integer':
|
|
326
|
-
case 'nonNegativeInteger':
|
|
327
|
-
case 'positiveInteger':
|
|
328
|
-
case 'nonPositiveInteger':
|
|
329
|
-
case 'negativeInteger':
|
|
330
|
-
case 'long':
|
|
331
|
-
if (typeof v === 'string') v = BigInt (v)
|
|
332
|
-
switch (typeof v) {
|
|
333
|
-
case 'number':
|
|
334
|
-
case 'bigint':
|
|
335
|
-
return '' + v
|
|
336
|
-
}
|
|
337
|
-
carp ()
|
|
338
|
-
|
|
339
|
-
case 'int':
|
|
340
|
-
case 'short':
|
|
341
|
-
case 'byte':
|
|
342
|
-
case 'unsignedLong':
|
|
343
|
-
case 'unsignedInt':
|
|
344
|
-
case 'unsignedShort':
|
|
345
|
-
case 'unsignedByte':
|
|
346
|
-
if (typeof v === 'string') v = parseInt (v)
|
|
347
|
-
switch (typeof v) {
|
|
348
|
-
case 'number':
|
|
349
|
-
if (!Number.isInteger (v)) carp ()
|
|
350
|
-
case 'bigint':
|
|
351
|
-
return '' + v
|
|
352
|
-
}
|
|
353
|
-
carp ()
|
|
354
|
-
|
|
355
|
-
case 'float':
|
|
356
|
-
case 'double':
|
|
357
|
-
if (typeof v === 'string') v = parseFloat (v)
|
|
358
|
-
if (typeof v === 'number') switch (v) {
|
|
359
|
-
case Number.POSITIVE_INFINITY: return 'INF'
|
|
360
|
-
case Number.NEGATIVE_INFINITY: return '-INF'
|
|
361
|
-
default: return '' + v
|
|
362
|
-
}
|
|
363
|
-
carp ()
|
|
364
|
-
|
|
365
|
-
case 'decimal':
|
|
366
|
-
const {fractionDigits} = restriction
|
|
367
|
-
if (typeof v === 'string') v = parseFloat (v)
|
|
368
|
-
if (typeof v === 'number') return fractionDigits ? v.toFixed (fractionDigits.value) : '' + v
|
|
369
|
-
carp ()
|
|
370
|
-
|
|
371
|
-
case 'QName':
|
|
372
|
-
if (typeof v === 'object' && 'localName' in v) v = this.ns.QName (v.localName, v.namespaceURI)
|
|
373
|
-
|
|
374
|
-
default:
|
|
375
|
-
return XML_ATTR.escape ('' + v)
|
|
376
|
-
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
|
|
381
185
|
}
|
|
382
186
|
|
|
383
|
-
XMLMarshaller.declaration = _declaration
|
|
384
|
-
|
|
385
187
|
module.exports = XMLMarshaller
|
package/lib/XMLNode.js
CHANGED
|
@@ -1,33 +1,16 @@
|
|
|
1
|
-
const os = require ('os')
|
|
2
1
|
const SAXEvent = require ('./SAXEvent.js')
|
|
3
2
|
const XMLPrinter = require ('./XMLPrinter.js')
|
|
4
|
-
const AttributesMap = require ('./AttributesMap')
|
|
5
3
|
const NamespacesMap = require ('./NamespacesMap')
|
|
6
4
|
const MoxyLikeJsonEncoder = require ('./MoxyLikeJsonEncoder')
|
|
7
5
|
|
|
8
|
-
const ENTITY_RESOLVER =
|
|
9
|
-
const ATTRIBUTES =
|
|
6
|
+
const ENTITY_RESOLVER = '_entityResolver'
|
|
7
|
+
const ATTRIBUTES = '_attributes'
|
|
10
8
|
const TYPE = Symbol ('_type')
|
|
11
9
|
const PARENT = Symbol ('_parent')
|
|
12
10
|
const LEVEL = Symbol ('_level')
|
|
13
|
-
const NS_MAP =
|
|
11
|
+
const NS_MAP = '_ns_map'
|
|
14
12
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const ESC = [
|
|
18
|
-
['<', '<'],
|
|
19
|
-
['>', '>'],
|
|
20
|
-
['&', '&'],
|
|
21
|
-
[String.fromCharCode (10), '
'],
|
|
22
|
-
[String.fromCharCode (13), '
'],
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
const ESC_BODY = new stringEscape (ESC)
|
|
26
|
-
const ESC_ATTR = new stringEscape ([...ESC, ['"', '"']])
|
|
27
|
-
|
|
28
|
-
const m2o =
|
|
29
|
-
Object.fromEntries ? m => Object.fromEntries (m.entries ()) :
|
|
30
|
-
m => {let o = {}; for (const [k, v] of m.entries ()) o [k] = v; return o}
|
|
13
|
+
const m2o = m => Object.fromEntries (m.entries ())
|
|
31
14
|
|
|
32
15
|
const XMLNode = class extends SAXEvent {
|
|
33
16
|
|
|
@@ -41,7 +24,7 @@ const XMLNode = class extends SAXEvent {
|
|
|
41
24
|
this [PARENT] = null
|
|
42
25
|
this [LEVEL] = 0
|
|
43
26
|
|
|
44
|
-
this.children =
|
|
27
|
+
this.children = []
|
|
45
28
|
|
|
46
29
|
}
|
|
47
30
|
|
|
@@ -77,6 +60,20 @@ const XMLNode = class extends SAXEvent {
|
|
|
77
60
|
|
|
78
61
|
}
|
|
79
62
|
|
|
63
|
+
get xml () {
|
|
64
|
+
|
|
65
|
+
switch (this.type) {
|
|
66
|
+
|
|
67
|
+
case SAXEvent.TYPES.END_DOCUMENT: return ''
|
|
68
|
+
|
|
69
|
+
case SAXEvent.TYPES.END_ELEMENT: return this.isSelfEnclosed ? '' : `</${this.name}>`
|
|
70
|
+
|
|
71
|
+
default: return this.src
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
80
77
|
readNamespaces () {
|
|
81
78
|
|
|
82
79
|
this [NS_MAP] = new NamespacesMap (this)
|
|
@@ -93,7 +90,7 @@ const XMLNode = class extends SAXEvent {
|
|
|
93
90
|
|
|
94
91
|
this [LEVEL] = 1 + _parent.level
|
|
95
92
|
|
|
96
|
-
const {children} = _parent;
|
|
93
|
+
const {children} = _parent; children.push (this)
|
|
97
94
|
|
|
98
95
|
}
|
|
99
96
|
|
|
@@ -122,25 +119,7 @@ const XMLNode = class extends SAXEvent {
|
|
|
122
119
|
return namespacesMap.getNamespaceURI (this.name, true)
|
|
123
120
|
|
|
124
121
|
}
|
|
125
|
-
|
|
126
|
-
readAttributes () {
|
|
127
|
-
|
|
128
|
-
const m = new AttributesMap (this [ENTITY_RESOLVER], this [NS_MAP])
|
|
129
122
|
|
|
130
|
-
this.writeAttributesToMap (m)
|
|
131
|
-
|
|
132
|
-
this [ATTRIBUTES] = m
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
get attributes () {
|
|
137
|
-
|
|
138
|
-
if (!(ATTRIBUTES in this)) this.readAttributes ()
|
|
139
|
-
|
|
140
|
-
return this [ATTRIBUTES]
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
123
|
toString (options, level = 0) {
|
|
145
124
|
|
|
146
125
|
if (arguments.length === 0) return this.toSourceString ()
|
|
@@ -181,32 +160,39 @@ const XMLNode = class extends SAXEvent {
|
|
|
181
160
|
|
|
182
161
|
}
|
|
183
162
|
|
|
184
|
-
|
|
185
|
-
|
|
163
|
+
detachChildren (list) {
|
|
164
|
+
|
|
186
165
|
if (!Array.isArray (list) || list.length === 0) return []
|
|
187
166
|
|
|
188
|
-
|
|
189
|
-
|
|
167
|
+
const a = []; for (const i of list) {
|
|
168
|
+
|
|
190
169
|
const d = i.detach (); if (d === null) continue
|
|
191
|
-
|
|
192
|
-
if (d instanceof String && last instanceof String) {
|
|
193
170
|
|
|
194
|
-
|
|
171
|
+
if (typeof d === 'string') {
|
|
172
|
+
|
|
173
|
+
let {length} = a; if (length !== 0) {
|
|
174
|
+
|
|
175
|
+
length --; if (typeof a [length] === 'string') {
|
|
176
|
+
|
|
177
|
+
a [length] += d
|
|
178
|
+
|
|
179
|
+
continue
|
|
180
|
+
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
}
|
|
195
184
|
|
|
196
185
|
}
|
|
197
|
-
else {
|
|
198
186
|
|
|
199
|
-
|
|
187
|
+
a.push (d)
|
|
200
188
|
|
|
201
|
-
}
|
|
202
|
-
|
|
203
189
|
}
|
|
204
|
-
|
|
190
|
+
|
|
205
191
|
return a
|
|
206
192
|
|
|
207
193
|
}
|
|
208
194
|
|
|
209
|
-
detach (
|
|
195
|
+
detach () {
|
|
210
196
|
|
|
211
197
|
switch (this.type) {
|
|
212
198
|
|
|
@@ -222,11 +208,9 @@ const XMLNode = class extends SAXEvent {
|
|
|
222
208
|
localName,
|
|
223
209
|
namespaceURI,
|
|
224
210
|
attributes : m2o (attributes),
|
|
225
|
-
children : this.
|
|
211
|
+
children : this.detachChildren (children),
|
|
226
212
|
}
|
|
227
213
|
|
|
228
|
-
if (o.nsMap) r.namespacesMap = m2o (namespacesMap || [])
|
|
229
|
-
|
|
230
214
|
return r
|
|
231
215
|
|
|
232
216
|
default:
|
package/lib/XMLParser.js
CHANGED
|
@@ -3,7 +3,7 @@ const SAXEvent = require ('./SAXEvent.js')
|
|
|
3
3
|
const XMLNode = require ('./XMLNode.js')
|
|
4
4
|
const XMLIterator = require ('./XMLIterator.js')
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const XMLParser = class {
|
|
7
7
|
|
|
8
8
|
constructor (options = {}) {
|
|
9
9
|
|
|
@@ -21,7 +21,6 @@ const XMLReader = class {
|
|
|
21
21
|
this.useNamespaces = options.useNamespaces
|
|
22
22
|
|
|
23
23
|
if (this.useEntities) this.entityResolver = new (require ('./EntityResolver.js')) ()
|
|
24
|
-
|
|
25
24
|
|
|
26
25
|
}
|
|
27
26
|
|
|
@@ -83,4 +82,4 @@ const XMLReader = class {
|
|
|
83
82
|
|
|
84
83
|
}
|
|
85
84
|
|
|
86
|
-
module.exports =
|
|
85
|
+
module.exports = XMLParser
|
package/lib/XMLPrinter.js
CHANGED
|
@@ -156,10 +156,16 @@ const XMLPrinter = class {
|
|
|
156
156
|
|
|
157
157
|
writeCharacters (value) {
|
|
158
158
|
|
|
159
|
-
if (this.stack.length === 0) throw Error ('No element started yet')
|
|
160
|
-
|
|
161
159
|
if (typeof value !== 'string') throw Error ('The text content must be a string, not ' + (typeof value))
|
|
162
160
|
|
|
161
|
+
return this.writeBody (this.ESC_BODY.escape (value))
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
writeBody (value) {
|
|
166
|
+
|
|
167
|
+
if (this.stack.length === 0) throw Error ('No element started yet')
|
|
168
|
+
|
|
163
169
|
if (value.length === 0) return this
|
|
164
170
|
|
|
165
171
|
if (this.isOpening) {
|
|
@@ -168,7 +174,7 @@ const XMLPrinter = class {
|
|
|
168
174
|
this.isOpening = false
|
|
169
175
|
}
|
|
170
176
|
|
|
171
|
-
this.text +=
|
|
177
|
+
this.text += value
|
|
172
178
|
|
|
173
179
|
return this
|
|
174
180
|
|