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/lib/XMLReader.js CHANGED
@@ -91,9 +91,7 @@ const XMLReader = class extends Transform {
91
91
 
92
92
  this.off (THE_END, nope)
93
93
 
94
- if (e.type === SAXEvent.TYPES.END_DOCUMENT) return nope ()
95
-
96
- const src = this [OPT_SRC]; if (src !== null) src.unpipe (this)
94
+ this [OPT_SRC].unpipe (this)
97
95
 
98
96
  ok (e)
99
97
 
@@ -233,17 +231,7 @@ const XMLReader = class extends Transform {
233
231
  this.publish (e, SAXEvent.TYPES.END_ELEMENT)
234
232
 
235
233
  }
236
- else {
237
-
238
- if (
239
-
240
- (this.element !== null && this.element.children !== null)
241
-
242
- ||
243
-
244
- (this.collect !== null && this.collect (e))
245
-
246
- ) e.children = []
234
+ else {
247
235
 
248
236
  this.element = e
249
237
 
package/lib/XMLSchema.js CHANGED
@@ -3,27 +3,69 @@ const TYPES = Symbol ('_types')
3
3
  const FORM_U = 'unqualified'
4
4
  const FORM_Q = 'qualified'
5
5
 
6
+ const adjustNode = node => {
7
+
8
+ node.children = node.children
9
+ .filter (i => i.localName !== 'annotation')
10
+ .map (node => adjustNode (node))
11
+
12
+ const {attributes, namespacesMap} = node, splitNs = name => {
13
+
14
+ if (!attributes.has (name)) return
15
+
16
+ const value = attributes.get (name), pos = value.indexOf (':')
17
+
18
+ attributes.set (name, [value.substring (pos + 1), namespacesMap.get (value.substring (0, pos))])
19
+
20
+ }
21
+
22
+ switch (node.localName) {
23
+
24
+ case 'attribute':
25
+ case 'element':
26
+ case 'group':
27
+ splitNs ('ref')
28
+ splitNs ('type')
29
+ break
30
+
31
+ case 'extension':
32
+ case 'restriction':
33
+ splitNs ('base')
34
+ break
35
+
36
+ }
37
+
38
+ return node
39
+
40
+ }
41
+
6
42
  const XMLSchema = class extends Map {
7
43
 
8
- constructor (parent, targetNamespace) {
44
+ static namespaceURI = 'http://www.w3.org/2001/XMLSchema'
45
+
46
+ constructor (parent, targetNamespace, node) {
9
47
 
10
48
  super ()
11
-
12
- this.parent = parent
13
-
14
- this.targetNamespace = targetNamespace
15
-
49
+
16
50
  this.formDefault = {}
17
-
51
+
18
52
  this [TYPES] = new Map ()
19
53
 
54
+ {(this.parent = parent).set (this.targetNamespace = targetNamespace, this)}
55
+
56
+ this.setSource (node)
57
+
20
58
  }
21
59
 
22
60
  getType (localName) {
61
+
23
62
  return this [TYPES].get (localName)
63
+
24
64
  }
25
65
 
26
- add (node, options = {}) {
66
+ setSource (node) {
67
+
68
+ node = adjustNode (node).detach ()
27
69
 
28
70
  const {attributes, children} = node
29
71
 
@@ -50,18 +92,16 @@ const XMLSchema = class extends Map {
50
92
 
51
93
  }
52
94
 
95
+ this._src = node
96
+
53
97
  }
54
98
 
55
99
  copyTargetNamespace (node, force = false) {
56
-
57
- if (typeof node !== 'object') return
58
100
 
59
101
  const {localName} = node
60
102
 
61
103
  for (const e of node.children) this.copyTargetNamespace (e, localName === 'schema')
62
104
 
63
- if ('targetNamespace' in node) return
64
-
65
105
  const {formDefault} = this; if (!(localName in formDefault)) return
66
106
 
67
107
  if (!force) {
@@ -76,50 +116,12 @@ const XMLSchema = class extends Map {
76
116
 
77
117
  }
78
118
 
79
- }
80
-
81
- XMLSchema.adjustNode = (node, recurse) => {
82
-
83
- if (node.children) {
84
-
85
- node.children = node.children.filter (i => i.localName !== 'annotation')
86
-
87
- if (recurse) node.children = node.children.map (node => XMLSchema.adjustNode (node, true))
88
-
89
- }
90
-
91
- const {attributes, namespacesMap} = node, splitNs = name => {
92
-
93
- if (!attributes.has (name)) return
94
-
95
- const v = attributes.get (name); if (Array.isArray (v)) return
96
-
97
- const [local, prefix] = v.split (':').reverse ()
98
-
99
- attributes.set (name, [local, namespacesMap.get (prefix || '')])
100
-
101
- }
102
-
103
- switch (node.localName) {
119
+ getSimpleTypeClass (node) {
104
120
 
105
- case 'attribute':
106
- case 'element':
107
- case 'group':
108
- splitNs ('ref')
109
- splitNs ('type')
110
- break
111
-
112
- case 'extension':
113
- case 'restriction':
114
- splitNs ('base')
115
- break
121
+ return this.parent.getSimpleTypeClass (node)
116
122
 
117
123
  }
118
124
 
119
- return node
120
-
121
125
  }
122
126
 
123
- XMLSchema.namespaceURI = 'http://www.w3.org/2001/XMLSchema'
124
-
125
127
  module.exports = XMLSchema
@@ -0,0 +1,29 @@
1
+ const fs = require ('fs')
2
+ const path = require ('path')
3
+
4
+ const XMLSchema = require ('./XMLSchema.js')
5
+ const {XSSimpleType} = require ('./XSSimpleType.js')
6
+
7
+ class XMLSchemaBuiltIn extends XMLSchema {
8
+
9
+ constructor (parent) {
10
+
11
+ const fn = path.join (__dirname, 'xsd.xsd')
12
+
13
+ const xml = fs.readFileSync (fn, 'utf-8')
14
+
15
+ const doc = parent.parser.process (xml)
16
+
17
+ super (parent, XMLSchema.namespaceURI, doc)
18
+
19
+ }
20
+
21
+ getSimpleTypeClass (node) {
22
+
23
+ return XSSimpleType.forName (node.attributes.name)
24
+
25
+ }
26
+
27
+ }
28
+
29
+ module.exports = XMLSchemaBuiltIn
@@ -0,0 +1,24 @@
1
+ const fs = require ('fs')
2
+ const path = require ('path')
3
+
4
+ const XMLSchema = require ('./XMLSchema.js')
5
+ const NamespacesMap = require ('./NamespacesMap.js')
6
+ const {XSSimpleType} = require ('./XSSimpleType.js')
7
+
8
+ class XMLSchemaXml extends XMLSchema {
9
+
10
+ constructor (parent) {
11
+
12
+ const fn = path.join (__dirname, 'xml.xsd')
13
+
14
+ const xml = fs.readFileSync (fn, 'utf-8')
15
+
16
+ const doc = parent.parser.process (xml)
17
+
18
+ super (parent, NamespacesMap.XMLNamespace, doc)
19
+
20
+ }
21
+
22
+ }
23
+
24
+ module.exports = XMLSchemaXml
@@ -1,16 +1,15 @@
1
- const assert = require ('assert')
2
-
3
1
  const fs = require ('fs')
4
2
  const path = require ('path')
5
3
 
4
+ const NamespacesMap = require ('./NamespacesMap.js')
6
5
  const XMLParser = require ('./XMLParser.js')
7
- const XMLReader = require ('./XMLReader.js')
8
- const XMLNode = require ('./XMLNode.js')
9
- const XMLSchema = require ('./XMLSchema.js'), {adjustNode} = XMLSchema
10
- const NamespacePrefixesMap = require ('./NamespacePrefixesMap.js')
11
- const {XMLNamespace, XMLSchemaNamespace} = require ('./NamespacesMap.js')
6
+ const XMLSchema = require ('./XMLSchema.js')
7
+ const XMLSchemaXml = require ('./XMLSchemaXml.js')
8
+ const XMLSchemaBuiltIn = require ('./XMLSchemaBuiltIn.js')
12
9
  const XMLMarshaller = require ('./XMLMarshaller.js')
13
10
 
11
+ const {XSSimpleType} = require ('./XSSimpleType.js')
12
+
14
13
  const IDX = Symbol ('_index')
15
14
 
16
15
  const XMLSchemata = class extends Map {
@@ -18,16 +17,17 @@ const XMLSchemata = class extends Map {
18
17
  constructor (fn) {
19
18
 
20
19
  super ()
21
-
22
- this [IDX] = new Map ()
23
-
20
+
24
21
  this.documents = []
25
22
 
26
- if (fn) {
27
- this.parser = new XMLParser ()
28
- this.addFileSync (fn)
29
- delete this.parser
30
- }
23
+ this [IDX] = new Map ()
24
+
25
+ this.parser = new XMLParser ()
26
+
27
+ new XMLSchemaXml (this)
28
+ new XMLSchemaBuiltIn (this)
29
+
30
+ this.addFile (fn)
31
31
 
32
32
  }
33
33
 
@@ -40,23 +40,56 @@ const XMLSchemata = class extends Map {
40
40
  idx.get (name).add (targetNamespace)
41
41
 
42
42
  }
43
+
44
+ getType ([localName, namespaceURI]) {
43
45
 
44
- getType (ref) {
46
+ const schema = this.get (namespaceURI); if (schema == null) throw new Error ('Unknown namespace: ' + namespaceURI)
45
47
 
46
- const [localName, namespaceURI] = ref
48
+ const node = schema.getType (localName)
49
+
50
+ if (node.localName === 'simpleType' && !node._xsSimpleType) node._xsSimpleType = new (schema.getSimpleTypeClass (node)) (this)
51
+
52
+ return node
53
+
54
+ }
55
+
56
+ getSimpleType (node) {
57
+
58
+ if ('_xsSimpleType' in node) return node._xsSimpleType
59
+
60
+ return node._xsSimpleType = new (this.getSimpleTypeClass (node)) (this)
47
61
 
48
- if (namespaceURI === XMLSchema.namespaceURI) return {
49
- localName: 'simpleType',
50
- namespaceURI,
51
- attributes: {name: localName},
52
- children: [],
53
- namespacesMap: {},
54
- targetNamespace: namespaceURI
55
- }
62
+ }
63
+
64
+ getSimpleTypeClass (node) {
56
65
 
57
- const s = this.get (namespaceURI); if (s == null) throw new Error ('Unknown namespace: ' + namespaceURI)
66
+ for (const {localName, namespaceURI, attributes: {base}, children} of node.children)
58
67
 
59
- return s.getType (localName)
68
+ if (localName === 'restriction' && namespaceURI === XMLSchema.namespaceURI)
69
+
70
+ return this.getType (base)._xsSimpleType.restrict (children.map (
71
+
72
+ ({localName, attributes: {value}}) => ({name: localName, value})
73
+
74
+ ))
75
+
76
+ return XSSimpleType
77
+
78
+ }
79
+
80
+ getAttributeSimpleTypeClass ({children: [child]}) {
81
+
82
+ return this.getSimpleTypeClass (child) // annotations are filtered out
83
+
84
+ }
85
+
86
+ getAttributeSimpleType (node) {
87
+
88
+ if ('_xsSimpleType' in node) return node._xsSimpleType
89
+
90
+ const {attributes: {type}} = node; if (type) return node._xsSimpleType = this.getType (type)._xsSimpleType
91
+
92
+ return node._xsSimpleType = new (this.getAttributeSimpleTypeClass (node)) (this)
60
93
 
61
94
  }
62
95
 
@@ -64,15 +97,6 @@ const XMLSchemata = class extends Map {
64
97
 
65
98
  const [localName, namespaceURI] = ref
66
99
 
67
- if (namespaceURI === XMLNamespace) return {
68
- localName: 'attribute',
69
- namespaceURI,
70
- attributes: {name: localName, type: ['string', XMLSchemaNamespace]},
71
- children: [],
72
- namespacesMap: {},
73
- targetNamespace: namespaceURI
74
- }
75
-
76
100
  const s = this.get (namespaceURI); if (s == null) throw new Error ('Unknown namespace: ' + namespaceURI)
77
101
 
78
102
  return s.get (localName)
@@ -91,125 +115,65 @@ const XMLSchemata = class extends Map {
91
115
 
92
116
  }
93
117
 
94
- createMarshaller (localName, namespaceURI) {
118
+ createMarshaller (localName, namespaceURI, printerOptions) {
95
119
 
96
120
  if (arguments.length === 1) namespaceURI = this.getSchemaByLocalName (localName).targetNamespace
97
121
 
98
- return new XMLMarshaller (this, localName, namespaceURI)
122
+ return new XMLMarshaller (this, localName, namespaceURI, printerOptions)
99
123
 
100
124
  }
101
125
 
102
126
  stringify (data, o) {
103
-
104
- assert.strictEqual (typeof data, 'object')
105
-
106
- assert.strictEqual (Object.keys (data).length, 1)
107
-
108
- for (let [localName, content] of Object.entries (data))
109
-
110
- return this.createMarshaller (localName).stringify (content, o)
111
-
112
- }
113
-
114
- async addSchema (node, options = {}) {
115
127
 
116
- let {targetNamespace} = node.attributes; if (!targetNamespace) targetNamespace = options.targetNamespace
128
+ if (data == null) throw Error ('Cannot stringify ' + data)
117
129
 
118
- if (!this.has (targetNamespace)) this.set (targetNamespace, new XMLSchema (this, targetNamespace))
119
-
120
- const imp = node.children.filter (e => e.localName === 'import' && e.namespaceURI === XMLSchema.namespaceURI)
121
-
122
- if (imp.length !== 0) await Promise.all (imp.map (i => {
123
-
124
- const {schemaLocation, namespace} = i.attributes
125
-
126
- return options.addLocation (schemaLocation, namespace)
127
-
128
- }))
129
-
130
- this.get (targetNamespace).add (node)
131
-
132
- }
133
-
134
- async addFile (fn, options = {}) {
135
-
136
- const dirname = path.dirname (fn), that = this, addLocation = async function (schemaLocation, namespace) {
137
-
138
- await that.addFile (path.join (dirname, schemaLocation), options = {targetNamespace: namespace})
139
-
140
- }
130
+ if (typeof data !== 'object') throw Error ('Not an Object instance: ' + data)
141
131
 
142
- const {targetNamespace} = options, mapper = n => n.detach ()
132
+ const entries = Object.entries (data), {length} = entries; if (length !== 1) throw Error ('The data object must have exactly 1 entry, found: ' + length)
143
133
 
144
- for await (const node of
145
-
146
- new XMLReader ({
147
- filterElements: e => e.namespaceURI === XMLSchema.namespaceURI,
148
- map: adjustNode,
149
- })
150
- .process (fs.createReadStream (fn))
151
-
152
- )
153
-
154
- if (node.localName === 'schema')
155
-
156
- await this.addSchema (mapper (node), {addLocation, targetNamespace})
134
+ const [[localName, content]] = entries; return this.createMarshaller (localName).stringify (content, o)
157
135
 
158
136
  }
159
137
 
160
- addSchemaSync (node, options = {}) {
138
+ addFromNode (node, options) {
161
139
 
162
- if (node.localName !== 'schema' || node.namespaceURI !== XMLSchema.namespaceURI) {
163
-
164
- const {children} = node; if (children) for (const i of children) this.addSchemaSync (i, options)
165
-
166
- return
140
+ if (node.localName === 'schema' && node.namespaceURI === XMLSchema.namespaceURI) return this.addSchema (node, options)
167
141
 
168
- }
169
-
170
- node = adjustNode (node, true).detach ()
142
+ for (const child of node.children) this.addFromNode (child, options)
171
143
 
172
- let targetNamespace = node.attributes.targetNamespace || options.targetNamespace
173
-
174
- if (targetNamespace && !this.has (targetNamespace)) this.set (targetNamespace, new XMLSchema (this, targetNamespace))
144
+ }
175
145
 
176
- const {addLocation} = options; for (const {localName, namespaceURI, attributes} of node.children)
146
+ addSchema (node, options) {
177
147
 
178
- if (localName === 'import' && namespaceURI === XMLSchema.namespaceURI)
148
+ const targetNamespace = node.attributes.get ('targetNamespace')
149
+
150
+ const schema = new XMLSchema (this, targetNamespace, node)
151
+
152
+ for (const {localName, namespaceURI, attributes: {schemaLocation, namespace}} of schema._src.children)
179
153
 
180
- addLocation (attributes.schemaLocation, attributes.namespace)
154
+ if (localName === 'import' && namespaceURI === XMLSchema.namespaceURI && namespace !== NamespacesMap.XMLNamespace)
181
155
 
182
- if (targetNamespace) this.get (targetNamespace).add (node)
156
+ this.addFile (path.join (options.dirname, schemaLocation), {targetNamespace: namespace})
183
157
 
184
158
  }
185
159
 
186
- addFileSync (fn, options = {}) {
187
-
188
- const dirname = path.dirname (fn), that = this
189
-
190
- options.addLocation = function (schemaLocation, namespace) {
191
-
192
- that.addFileSync (path.join (dirname, schemaLocation), {targetNamespace: namespace})
160
+ addFile (fn, options = {}) {
193
161
 
194
- }
162
+ options.dirname = path.dirname (fn)
195
163
 
196
164
  const document = this.parser.process (fs.readFileSync (fn, 'utf-8'))
197
165
 
198
166
  this.documents.push (document)
199
167
 
200
- this.addSchemaSync (document, options)
168
+ this.addFromNode (document, options)
201
169
 
202
170
  }
203
171
 
204
- }
172
+ static async fromFile (fn) {
205
173
 
206
- XMLSchemata.fromFile = async function (fn, options = {}) {
174
+ return new XMLSchemata (fn)
207
175
 
208
- let xs = new XMLSchemata ()
209
-
210
- await xs.addFile (fn, options)
211
-
212
- return xs
176
+ }
213
177
 
214
178
  }
215
179