xml-toolkit 1.0.7 → 1.0.8

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.
@@ -37,148 +37,163 @@ const XMLMarshaller = class {
37
37
 
38
38
  }
39
39
 
40
- stringify (content, name) {
41
-
42
- const qName = this.ns.QName (name || this.schemaElement.name, this.schema.targetNamespace)
43
-
44
- let {complexType, sequence, choice, all, type} = this.schemaElement, group = sequence || choice || all
45
-
46
- if (type) {
47
-
48
- type = this.xs.getByReference (type)
49
-
50
- switch (type._type) {
51
-
52
- case 'complexType':
53
- complexType = type
54
- break
40
+ stringify (data, name) {
41
+
42
+ const {schemaElement} = this, {targetNamespace, attributes, children} = schemaElement
55
43
 
56
- case 'simpleType':
57
- simpleType = type
58
- break
44
+ const qName = this.ns.QName (name || attributes.name, targetNamespace)
59
45
 
60
- }
61
-
62
- }
63
-
64
- let buf = ['<' + qName]
46
+ this.buf = ['<' + qName]
65
47
 
66
- this.ns.appendTo (buf)
48
+ this.ns.appendTo (this.buf)
67
49
 
68
- if (complexType) this._aComplexType (buf, complexType, content)
50
+ this.appendAttributes (schemaElement, data)
69
51
 
70
- buf [0] += '>'
52
+ this.buf [0] += '>'
53
+
54
+ this.appendElementBody (schemaElement, data)
55
+
56
+ const xml = this.buf [0] + '</' + qName + '>'
71
57
 
72
- if (complexType) this._bComplexType (buf, complexType, content)
73
- if (group) this._bSequence (buf, group, content)
58
+ delete this.buf
74
59
 
75
- return buf [0] + '</' + qName + '>'
60
+ return xml
76
61
 
77
62
  }
63
+
64
+ appendNullElement (node) {
78
65
 
79
- /// _a: attributes
66
+ const {attributes: {name, nillable}, targetNamespace} = node
80
67
 
81
- _aComplexType (buf, complexType, content) {
68
+ if (BOOL.get (nillable) !== 'true') return
82
69
 
83
- const {complexContent, attribute} = complexType
70
+ const qName = this.ns.QName (name, targetNamespace)
84
71
 
85
- if (attribute)
86
- for (const e of Array.isArray (attribute) ? attribute : [attribute])
87
- this._aAttribute (buf, e, content [e.name])
88
-
89
- if (complexContent) this._aComplexContent (buf, complexContent, content)
90
-
91
- }
92
-
93
- _aComplexContent (buf, complexContent, content) {
94
-
95
- const {extension} = complexContent
72
+ this.buf [0] += `<${qName} xsi:nil="true" />`
96
73
 
97
- if (extension) this._aExtension (buf, extension, content)
98
-
99
74
  }
100
75
 
101
- _aExtension (buf, extension, content) {
76
+ appendScalar (node, data, restriction = {}) {
102
77
 
103
- const {base, attribute} = extension
78
+ for (const {localName, attributes, children} of node.children) {
104
79
 
105
- if (base) {
106
-
107
- const [localName, namespaceURI] = base
108
-
109
- const schema = this.xs.get (namespaceURI)
110
-
111
- const type = schema.get (localName)
80
+ if (localName === 'restriction') {
81
+
82
+ for (const {localName, attributes: {value}} of children) restriction [localName] = value
83
+
84
+ return this.appendScalar (this.xs.getByReference (attributes.base), data, restriction)
85
+
86
+ }
112
87
 
113
- if (type._type === 'complexType') this._aComplexType (buf, type, content)
114
-
115
88
  }
116
89
 
117
- if (attribute)
118
- for (const a of Array.isArray (attribute) ? attribute : [attribute])
119
- this._aAttribute (buf, a, content [a.name])
90
+ this.buf [0] += this.to_string (data, node.attributes.name, restriction)
120
91
 
121
- }
92
+ }
122
93
 
123
- _aAttribute (buf, attribute, content) {
94
+ appendElementBody (node, data) {
124
95
 
125
- if (content == null) return
96
+ const {attributes: {type}, children} = node
126
97
 
127
- let {name, targetNamespace, simpleType, type} = attribute
128
-
129
- if (type) {
98
+ if (type) return this.appendContent (this.xs.getByReference (type), data)
130
99
 
131
- type = this.xs.getByReference (type)
100
+ for (const i of children) this.appendContent (i, data)
132
101
 
133
- switch (type._type) {
102
+ }
134
103
 
135
- case 'simpleType':
136
- simpleType = type
137
- break
104
+ appendAttributes (node, data) {
138
105
 
139
- }
106
+ const {localName, namespaceURI, attributes, children, targetNamespace} = node, {name, type, ref} = attributes
140
107
 
141
- }
108
+ if (ref) return this.appendAttributes (this.xs.getByReference (ref), data)
109
+
110
+ switch (localName) {
142
111
 
143
- const qName = this.ns.QName (name, targetNamespace)
144
-
145
- buf [0] += ' ' + qName + '="'
146
-
147
- if (simpleType) this._bSimpleType (buf, simpleType, content)
112
+ case 'simpleType':
113
+
114
+ return this.appendScalar (node, data)
115
+
116
+ case 'attribute':
117
+
118
+ if (!(name in data)) return
119
+
120
+ let v = data [name]; if (v == null) return
121
+
122
+ this.buf [0] += ' ' + this.ns.QName (name, targetNamespace) + '="'
123
+
124
+ this.appendScalar (this.xs.getByReference (type), v)
125
+
126
+ this.buf [0] += '"'
127
+
128
+ break
129
+
130
+ case 'extension':
148
131
 
149
- buf [0] += '"'
132
+ this.appendAttributes (this.xs.getByReference (attributes.base), data)
133
+
134
+ case 'any':
135
+ case 'sequence':
136
+ case 'choice':
137
+ case 'group':
150
138
 
151
- }
152
-
153
- /// _b: body
154
-
155
- _bComplexType (buf, complexType, content) {
139
+ return
156
140
 
157
- const {complexContent, sequence, choice, all} = complexType, group = sequence || choice || all
141
+ default:
158
142
 
159
- if (group) this._bSequence (buf, group, content)
160
- if (complexContent) this._bComplexContent (buf, complexContent, content)
143
+ for (const i of children) this.appendAttributes (i, data)
144
+
145
+ }
161
146
 
162
147
  }
148
+
149
+ appendContent (node, data) {
163
150
 
164
- _bSimpleType (buf, simpleType, content, _restriction = {}) {
151
+ const {localName, namespaceURI, attributes, children, targetNamespace} = node, {name, type, ref} = attributes
165
152
 
166
- let {restriction} = simpleType; if (restriction) {
153
+ if (ref) return this.appendContent (this.xs.getByReference (ref), data)
167
154
 
168
- for (const [k, v] of Object.entries (_restriction)) switch (k) {
169
- case 'base': case 'targetNamespace': break
170
- default: restriction [k] = v
171
- }
155
+ switch (localName) {
156
+
157
+ case 'simpleType':
158
+
159
+ return this.appendScalar (node, data)
172
160
 
173
- this._bSimpleType (buf, this.xs.getByReference (restriction.base), content, restriction)
161
+ case 'element':
174
162
 
175
- }
176
- else {
163
+ if (!(name in data)) return
164
+
165
+ let v = data [name]; if (v == null) return this.appendNullElement (node)
166
+
167
+ if (!Array.isArray (v)) v = [v]
168
+
169
+ const qName = this.ns.QName (name, targetNamespace)
170
+
171
+ for (const d of Array.isArray (v) ? v : [v]) {
172
+
173
+ this.buf [0] += '<' + qName
174
+
175
+ this.appendAttributes (node, d)
177
176
 
178
- buf [0] += this.to_string (content, simpleType.name, _restriction)
177
+ this.buf [0] += '>'
178
+
179
+ this.appendElementBody (node, d)
180
+
181
+ this.buf [0] += '</' + qName + '>'
182
+
183
+ }
179
184
 
185
+ break
186
+
187
+ case 'extension':
188
+
189
+ this.appendContent (this.xs.getByReference (attributes.base), data)
190
+
191
+ default:
192
+
193
+ for (const i of children) this.appendContent (i, data)
194
+
180
195
  }
181
-
196
+
182
197
  }
183
198
 
184
199
  to_string (v, type, restriction = {}) {
@@ -277,125 +292,6 @@ const XMLMarshaller = class {
277
292
 
278
293
  }
279
294
 
280
- _bComplexContent (buf, complexContent, content) {
281
-
282
- const {extension} = complexContent
283
-
284
- if (extension) this._bExtension (buf, extension, content)
285
-
286
- }
287
-
288
- _bExtension (buf, _extension, content) {
289
-
290
- const {base, sequence, choice, all} = _extension, group = sequence || choice || all
291
-
292
- if (base) {
293
-
294
- const [localName, namespaceURI] = base
295
-
296
- const schema = this.xs.get (namespaceURI)
297
-
298
- const type = schema.get (localName)
299
-
300
- if (type._type === 'complexType') this._bComplexType (buf, type, content)
301
-
302
- }
303
-
304
- if (group) this._bSequence (buf, group, content)
305
-
306
- }
307
-
308
- _bSequence (buf, _sequence, content) {
309
-
310
- const {element, sequence, choice, all, group} = _sequence, g = sequence || choice || all
311
-
312
- if (g) this._bSequence (buf, g, content)
313
-
314
- if (element) {
315
-
316
- for (let e of Array.isArray (element) ? element : [element]) {
317
-
318
- const {ref} = e; if (ref) e = this.xs.getByReference (ref)
319
-
320
- const c = content [e.name]
321
-
322
- this._bElement (buf, e, c)
323
-
324
- }
325
-
326
- }
327
-
328
- if (group) {
329
-
330
- for (let e of Array.isArray (group) ? group : [group]) {
331
-
332
- const {ref} = e; if (ref) e = this.xs.getByReference (ref)
333
-
334
- this._bSequence (buf, e, content)
335
-
336
- }
337
-
338
- }
339
-
340
- }
341
-
342
- _bElement_null (buf, element) {
343
-
344
- if (BOOL.get (element.nillable) !== 'true') return
345
-
346
- const {name, targetNamespace} = element, qName = this.ns.QName (name, targetNamespace)
347
-
348
- buf [0] += `<${qName} xsi:nil="true" />`
349
-
350
- }
351
-
352
- _bElement (buf, element, content) {
353
-
354
- if (content == null) return this._bElement_null (buf, element)
355
-
356
- if (!Array.isArray (content)) content = [content]
357
-
358
- if (content.length === 0) return
359
-
360
- let {name, targetNamespace, complexType, simpleType, type} = element
361
-
362
- if (type) {
363
-
364
- type = this.xs.getByReference (type)
365
-
366
- switch (type._type) {
367
-
368
- case 'complexType':
369
- complexType = type
370
- break
371
-
372
- case 'simpleType':
373
- simpleType = type
374
- break
375
-
376
- }
377
-
378
- }
379
-
380
- const qName = this.ns.QName (name, targetNamespace)
381
-
382
- for (const i of content) {
383
-
384
- buf [0] += '<' + qName
385
-
386
- if (complexType) this._aComplexType (buf, complexType, content)
387
-
388
- buf [0] += '>'
389
-
390
- if (complexType) this._bComplexType (buf, complexType, i)
391
- if (simpleType) this._bSimpleType (buf, simpleType, i)
392
-
393
- buf [0] += '</' + qName + '>'
394
-
395
- }
396
-
397
- }
398
-
399
295
  }
400
296
 
401
297
  module.exports = XMLMarshaller
package/lib/XMLNode.js CHANGED
@@ -132,6 +132,35 @@ const XMLNode = class extends SAXEvent {
132
132
 
133
133
  }
134
134
 
135
+ detach (o = {}) {
136
+
137
+ switch (this.type) {
138
+
139
+ case SAXEvent.TYPES.CHARACTERS:
140
+ case SAXEvent.TYPES.CDATA:
141
+ return this.text
142
+
143
+ default:
144
+
145
+ const m2o = m => Object.fromEntries (m.entries ())
146
+
147
+ const {localName, namespaceURI, attributes, children, namespacesMap} = this
148
+
149
+ let r = {
150
+ localName,
151
+ namespaceURI,
152
+ attributes : m2o (attributes),
153
+ children : (children || []).map (n => n.detach (o)),
154
+ }
155
+
156
+ if (o.nsMap) r.namespacesMap = m2o (namespacesMap || [])
157
+
158
+ return r
159
+
160
+ }
161
+
162
+ }
163
+
135
164
  }
136
165
 
137
166
  XMLNode.getLocalName = name => {
package/lib/XMLSchema.js CHANGED
@@ -13,57 +13,33 @@ const XMLSchema = class extends Map {
13
13
  }
14
14
 
15
15
  add (node, options = {}) {
16
+
17
+ this.copyTargetNamespace (node)
18
+
19
+ const {attributes, children} = node
16
20
 
17
- if (node.elementFormDefault === 'unqualified') this.isDefaultElementFormQualified = false
18
- if (node.attributeFormDefault === 'qualified') this.isAttributeElementFormQualified = true
19
-
20
- for (const type of [
21
-
22
- 'element',
23
- 'complexType',
24
- 'simpleType',
25
- 'group',
26
-
27
- ]) if (type in node) {
28
-
29
- let list = node [type]
30
-
31
- if (!Array.isArray (list)) list = [list]
21
+ if (attributes.elementFormDefault === 'unqualified') this.isDefaultElementFormQualified = false
22
+ if (attributes.attributeFormDefault === 'qualified') this.isAttributeElementFormQualified = true
23
+
24
+ for (const e of children) {
25
+
26
+ const {name} = e.attributes
32
27
 
33
- for (const item of list) {
28
+ this.set (name, e)
34
29
 
35
- delete item.annotation
36
-
37
- item._type = type
38
-
39
- this.copyTargetNamespace (item)
40
-
41
- this.set (item.name, item)
42
-
43
- this.parent.register (item.name, this.targetNamespace)
44
-
45
- }
46
-
30
+ this.parent.register (name, this.targetNamespace)
31
+
47
32
  }
48
33
 
49
34
  }
50
35
 
51
- copyTargetNamespace (o) {
52
-
53
- if (typeof o !== 'object') return
36
+ copyTargetNamespace (node) {
54
37
 
55
- if (Array.isArray (o)) {
38
+ if (typeof node !== 'object') return
56
39
 
57
- for (const v of o) this.copyTargetNamespace (v)
58
-
59
- }
60
- else {
61
-
62
- o.targetNamespace = this.targetNamespace
40
+ node.targetNamespace = this.targetNamespace
63
41
 
64
- for (const v of Object.values (o)) this.copyTargetNamespace (v)
65
-
66
- }
42
+ for (const e of node.children) this.copyTargetNamespace (e)
67
43
 
68
44
  }
69
45
 
@@ -103,4 +79,6 @@ XMLSchema.adjustNode = node => {
103
79
 
104
80
  }
105
81
 
82
+ XMLSchema.namespaceURI = 'http://www.w3.org/2001/XMLSchema'
83
+
106
84
  module.exports = XMLSchema
@@ -35,9 +35,13 @@ const XMLSchemata = class extends Map {
35
35
 
36
36
  const [localName, namespaceURI] = ref
37
37
 
38
- if (namespaceURI === 'http://www.w3.org/2001/XMLSchema') return {
39
- _type: 'simpleType',
40
- name: localName
38
+ if (namespaceURI === XMLSchema.namespaceURI) return {
39
+ localName: 'simpleType',
40
+ namespaceURI,
41
+ attributes: {name: localName},
42
+ children: [],
43
+ namespacesMap: {},
44
+ targetNamespace: namespaceURI
41
45
  }
42
46
 
43
47
  return this.get (namespaceURI).get (localName)
@@ -83,21 +87,21 @@ const XMLSchemata = class extends Map {
83
87
  }
84
88
 
85
89
  async addSchema (node, options = {}) {
86
-
87
- let {targetNamespace} = node; if (!targetNamespace) targetNamespace = options.targetNamespace
90
+
91
+ let {targetNamespace} = node.attributes; if (!targetNamespace) targetNamespace = options.targetNamespace
88
92
 
89
93
  if (!this.has (targetNamespace)) this.set (targetNamespace, new XMLSchema (this, targetNamespace))
90
94
 
91
- let imp = node.import; if (imp) {
95
+ const imp = node.children.filter (e => e.localName === 'import' && e.namespaceURI === XMLSchema.namespaceURI)
92
96
 
93
- const {addLocation} = options
97
+ if (imp.length !== 0) await Promise.all (imp.map (i => {
94
98
 
95
- if (!Array.isArray (imp)) imp = [imp]
99
+ const {schemaLocation, namespace} = i.attributes
96
100
 
97
- for (const {schemaLocation, namespace} of imp) await addLocation (schemaLocation, namespace)
101
+ return options.addLocation (schemaLocation, namespace)
102
+
103
+ }))
98
104
 
99
- }
100
-
101
105
  this.get (targetNamespace).add (node)
102
106
 
103
107
  }
@@ -110,12 +114,12 @@ const XMLSchemata = class extends Map {
110
114
 
111
115
  }
112
116
 
113
- const {targetNamespace} = options, mapper = XMLNode.toObject ({})
117
+ const {targetNamespace} = options, mapper = n => n.detach ({nsMap: true})
114
118
 
115
119
  for await (const node of
116
120
 
117
121
  new XMLReader ({
118
- filterElements: e => e.namespaceURI === 'http://www.w3.org/2001/XMLSchema',
122
+ filterElements: e => e.namespaceURI === XMLSchema.namespaceURI,
119
123
  map: adjustNode,
120
124
  })
121
125
  .process (fs.createReadStream (fn))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xml-toolkit",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Collection of classes for dealing with XML",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test/test.js CHANGED
@@ -59,12 +59,15 @@ console.log (xml)
59
59
 
60
60
  const sax = new XMLReader ({
61
61
  // stripSpace: true,
62
+ // filterElements: 'root',
63
+ // filterElements: 'PARAMTYPES'
62
64
  filterElements: 'SendRequestRequest',
63
- map: XMLNode.toObject ({
65
+ map: n => n.detach ({nsMap: true}),
66
+ // map: XMLNode.toObject ({
64
67
  // wrap: 1,
65
- getName: (localName, namespaceURI) => (!namespaceURI ? '' : '{' + namespaceURI + '}') + localName,
66
- map: o => Object.fromEntries (Object.entries (o).map (([k, v]) => [k + '111', v]))
67
- })
68
+ // getName: (localName, namespaceURI) => (!namespaceURI ? '' : '{' + namespaceURI + '}') + localName,
69
+ // map: o => Object.fromEntries (Object.entries (o).map (([k, v]) => [k + '111', v]))
70
+ // })
68
71
  })
69
72
 
70
73
  /*
@@ -111,8 +114,13 @@ async function test_004_schemata (fn) {
111
114
  const o = s.get (localName)
112
115
 
113
116
  const nspm = xs.getNamespacePrefixesMap (o)
114
- */
117
+ */
118
+
115
119
  console.log (xs.stringify ({
120
+ "ExportDebtRequestsRequest": {Id: 1}
121
+ }))
122
+
123
+ if (0) console.log (xs.stringify ({
116
124
  "ExportDebtRequestsResponse": {
117
125
  "request-data": {
118
126
  "request-id": "bac4c940-6ad3-11eb-9439-0242ac130002",
@@ -315,11 +323,11 @@ async function main () {
315
323
  // await test_003_emitter_sync ('E05a.xml')
316
324
  // await test_003_emitter_sync ('param_types.xml')
317
325
  // await test_003_emitter_sync ('not-sa01.xml')
318
- // await test_003_emitter_sync ('ent.xml')
326
+ // await test_003_emitter_sync ('ent.xml')
319
327
  // await test_003_emitter_sync ('soap.xml')
320
- await test_004_schemata ()
328
+ // await test_004_schemata ()
321
329
  await test_005_schemata ()
322
- await test_006_schemata ()
330
+ // await test_006_schemata ()
323
331
 
324
332
  }
325
333