xml-toolkit 0.0.3 → 0.0.4

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/index.js CHANGED
@@ -1,6 +1,7 @@
1
- const XMLLexer = require ('./lib/XMLLexer')
2
- const SAXEventEmitter = require ('./lib/SAXEventEmitter')
3
- const SAXEvent = require ('./lib/SAXEvent')
4
- const AttributesMap = require ('./lib/AttributesMap')
1
+ const XMLLexer = require ('./lib/XMLLexer')
2
+ const XMLReader = require ('./lib/XMLReader')
3
+ const SAXEvent = require ('./lib/SAXEvent')
4
+ const AttributesMap = require ('./lib/AttributesMap')
5
+ const MoxyLikeJsonEncoder = require ('./lib/MoxyLikeJsonEncoder')
5
6
 
6
- module.exports = {SAXEventEmitter, XMLLexer, SAXEvent, AttributesMap}
7
+ module.exports = {XMLLexer, XMLReader, SAXEvent, AttributesMap, MoxyLikeJsonEncoder}
@@ -1,35 +1,72 @@
1
+ const CH_COLON = ':'.charCodeAt (0)
2
+
1
3
  const AttributesMap = class extends Map {
2
4
 
3
- constructor (xmlReader) {
5
+ constructor (xmlReader, nsMap = null) {
4
6
 
5
7
  super ()
6
-
8
+
7
9
  this._xmlReader = xmlReader
10
+ this._nsMap = nsMap
11
+
12
+ this.fixText = xmlReader.fixText
13
+
14
+ }
15
+
16
+ getLocalName (name) {
17
+
18
+ return (require ('./XMLNode.js')).getLocalName (name)
19
+
20
+ }
21
+
22
+ getNamespaceURI (name) {
23
+
24
+ return this._nsMap.getNamespaceURI (name)
25
+
26
+ }
27
+
28
+ get (name, namespaceURI = null) {
29
+
30
+ if (namespaceURI === null) return super.get (name)
8
31
 
9
- this.fix = null
10
-
11
- if (xmlReader.useEntities) {
32
+ for (const k of this._nsMap.getQNames (name, namespaceURI)) {
12
33
 
13
- const {entityResolver} = xmlReader
34
+ if (!this.has (k)) continue
14
35
 
15
- this.fix = s => entityResolver.fix (s)
16
-
17
- }
36
+ return this.get (k)
18
37
 
38
+ }
39
+
19
40
  }
20
41
 
21
42
  set (k, v) {
22
43
 
23
- {
24
-
25
- const {fix} = this
26
-
27
- if (fix !== null) v = fix (v)
44
+ const {_nsMap} = this; if (_nsMap !== null) {
45
+
46
+ if (k.slice (0, 5) === 'xmlns') {
47
+
48
+ if (k.length === 5) {
49
+
50
+ _nsMap.set ('', v)
51
+
52
+ return this
53
+
54
+ }
55
+
56
+ if (k.charCodeAt (5) === CH_COLON) {
57
+
58
+ _nsMap.set (k.slice (6), v)
59
+
60
+ return this
61
+
62
+ }
63
+
64
+ }
28
65
 
29
66
  }
30
67
 
31
- return super.set (k, v)
32
-
68
+ return super.set (k, this.fixText (v))
69
+
33
70
  }
34
71
 
35
72
  }
@@ -0,0 +1,41 @@
1
+ const SAXEvent = require ('./SAXEvent.js')
2
+
3
+ const set = (o, k, nv) => {
4
+
5
+ if (!(k in o)) return o [k] = nv
6
+
7
+ const ov = o [k]; if (!Array.isArray (ov)) o [k] = [ov]
8
+
9
+ o [k].push (nv)
10
+
11
+ }
12
+
13
+ const xform = ({children, attributes}) => {
14
+
15
+ let o = Object.fromEntries (attributes.entries ())
16
+
17
+ if (children !== null) for (const child of children) switch (child.type) {
18
+
19
+ case SAXEvent.TYPES.CHARACTERS: return child.text
20
+
21
+ case SAXEvent.TYPES.END_ELEMENT: set (o, child.localName, xform (child))
22
+
23
+ }
24
+
25
+ return o
26
+
27
+ }
28
+
29
+ const MoxyLikeJsonEncoder = function (options = {}) {
30
+
31
+ return function (node) {
32
+
33
+ let result = xform (node)
34
+
35
+ return options.wrap ? {[node.localName]: result} : result
36
+
37
+ }
38
+
39
+ }
40
+
41
+ module.exports = MoxyLikeJsonEncoder
@@ -0,0 +1,48 @@
1
+ const NamespacesMap = class extends Map {
2
+
3
+ constructor (xmlNode) {
4
+
5
+ const {parent} = xmlNode
6
+
7
+ if (parent === null) {
8
+
9
+ super ()
10
+
11
+ }
12
+ else {
13
+
14
+ super (parent.namespacesMap)
15
+
16
+ }
17
+
18
+ }
19
+
20
+ getNamespaceURI (name, useDefault = false) {
21
+
22
+ const pos = name.indexOf (':'), noColon = pos === -1
23
+
24
+ if (noColon && !useDefault) return null
25
+
26
+ const key = noColon ? '' : name.slice (0, pos)
27
+
28
+ if (!this.has (key)) return null
29
+
30
+ return this.get (key)
31
+
32
+ }
33
+
34
+ * getQNames (localName, namespaceURI) {
35
+
36
+ for (let [k, v] of this.entries ())
37
+
38
+ if (v === namespaceURI)
39
+
40
+ yield k === '' ? localName :
41
+
42
+ k + ':' + localName
43
+
44
+ }
45
+
46
+ }
47
+
48
+ module.exports = NamespacesMap
package/lib/SAXEvent.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const assert = require ('assert')
2
2
 
3
3
  const CH_LT = '<'.charCodeAt (0)
4
+ const CH_GT = '>'.charCodeAt (0)
4
5
  const CH_EXCLAMATION = '!'.charCodeAt (0)
5
6
  const CH_QUESTION = '?'.charCodeAt (0)
6
7
  const CH_SLASH = '/'.charCodeAt (0)
@@ -46,7 +47,7 @@ const SAXEvent = class {
46
47
 
47
48
  case CH_QUESTION:
48
49
 
49
- switch (src.slice (2, 5).toLowerCase ()) {
50
+ switch (src.slice (2, 5).toUpperCase ()) {
50
51
 
51
52
  case STR_XML: return START_DOCUMENT
52
53
 
@@ -106,6 +107,38 @@ const SAXEvent = class {
106
107
 
107
108
  }
108
109
 
110
+ get name () {
111
+
112
+ if (this._afterName === 0) this.findAfterName ()
113
+
114
+ const {src} = this, start = src.charCodeAt (1) === CH_SLASH ? 2 : 1
115
+
116
+ return this.src.slice (start, this._afterName).trim ()
117
+
118
+ }
119
+
120
+ findAfterName () {
121
+
122
+ const {src} = this, {length} = src;
123
+
124
+ for (let i = 1; i < length; i ++) {
125
+
126
+ const c = src.charCodeAt (i)
127
+
128
+ switch (c) {
129
+ case CH_SLASH:
130
+ case CH_GT:
131
+ return this._afterName = i
132
+ }
133
+
134
+ if (c <= 32) return this._afterName = i
135
+
136
+ }
137
+
138
+ this._afterName = length - 1
139
+
140
+ }
141
+
109
142
  writeAttributesToMap (m) {
110
143
 
111
144
  const {src} = this
package/lib/XMLNode.js ADDED
@@ -0,0 +1,128 @@
1
+ const SAXEvent = require ('./SAXEvent.js')
2
+ const AttributesMap = require ('./AttributesMap')
3
+ const NamespacesMap = require ('./NamespacesMap')
4
+
5
+ const XML_READER = Symbol ('_xmlReader')
6
+ const ATTRIBUTES = Symbol ('_attributes')
7
+ const TYPE = Symbol ('_type')
8
+ const PARENT = Symbol ('_parent')
9
+ const LEVEL = Symbol ('_level')
10
+ const NS_MAP = Symbol ('_ns_map')
11
+
12
+ const XMLNode = class extends SAXEvent {
13
+
14
+ constructor (src, xmlReader, _type) {
15
+
16
+ super (src)
17
+
18
+ this [TYPE] = _type || super.type
19
+
20
+ this [XML_READER] = xmlReader
21
+ this [PARENT] = null
22
+ this [LEVEL] = 0
23
+
24
+ this.children = null
25
+
26
+ }
27
+
28
+ get level () {
29
+
30
+ return this [LEVEL]
31
+
32
+ }
33
+
34
+ get parent () {
35
+
36
+ return this [PARENT]
37
+
38
+ }
39
+
40
+ get namespacesMap () {
41
+
42
+ return this [NS_MAP]
43
+
44
+ }
45
+
46
+ readNamespaces () {
47
+
48
+ this [NS_MAP] = new NamespacesMap (this)
49
+
50
+ this.readAttributes ()
51
+
52
+ }
53
+
54
+ set parent (_parent) {
55
+
56
+ if (_parent == null) return
57
+
58
+ this [PARENT] = _parent
59
+
60
+ this [LEVEL] = 1 + _parent.level
61
+
62
+ const {children} = _parent; if (children !== null) children.push (this)
63
+
64
+ }
65
+
66
+ get type () {
67
+
68
+ return this [TYPE]
69
+
70
+ }
71
+
72
+ set type (_type) {
73
+
74
+ this [TYPE] = _type
75
+
76
+ }
77
+
78
+ get localName () {
79
+
80
+ return XMLNode.getLocalName (this.name)
81
+
82
+ }
83
+
84
+ get namespaceURI () {
85
+
86
+ return this.namespacesMap.getNamespaceURI (this.name, true)
87
+
88
+ }
89
+
90
+ readAttributes () {
91
+
92
+ const m = new AttributesMap (this [XML_READER], this [NS_MAP])
93
+
94
+ this.writeAttributesToMap (m)
95
+
96
+ this [ATTRIBUTES] = m
97
+
98
+ }
99
+
100
+ get attributes () {
101
+
102
+ if (!(ATTRIBUTES in this)) this.readAttributes ()
103
+
104
+ return this [ATTRIBUTES]
105
+
106
+ }
107
+
108
+ get text () {
109
+
110
+ let s = super.text
111
+
112
+ if (this [TYPE] === SAXEvent.TYPES.CHARACTERS) s = this [XML_READER].fixText (s)
113
+
114
+ return s
115
+
116
+ }
117
+
118
+ }
119
+
120
+ XMLNode.getLocalName = name => {
121
+
122
+ const pos = name.indexOf (':'); if (pos === -1) return name
123
+
124
+ return name.slice (pos + 1)
125
+
126
+ }
127
+
128
+ module.exports = XMLNode
package/lib/XMLReader.js CHANGED
@@ -1,6 +1,11 @@
1
1
  const assert = require ('assert')
2
2
  const {Transform} = require ('stream')
3
3
  const SAXEvent = require ('./SAXEvent.js')
4
+ const XMLNode = require ('./XMLNode.js')
5
+
6
+ const OPT_ONCE = Symbol ('_once')
7
+ const OPT_SRC = Symbol ('_src')
8
+ const OPT_SAX = Symbol ('_sax')
4
9
 
5
10
  const XMLReader = class extends Transform {
6
11
 
@@ -15,14 +20,41 @@ const XMLReader = class extends Transform {
15
20
  if (!('useEntities' in options)) options.useEntities = true
16
21
  assert (options.useEntities === true || options.useEntities === false, 'options.useEntities must be boolean, not ' + typeof options.useEntities)
17
22
 
23
+ if (!('useNamespaces' in options)) options.useNamespaces = true
24
+ assert (options.useNamespaces === true || options.useNamespaces === false, 'options.useNamespaces must be boolean, not ' + typeof options.useNamespaces)
25
+
26
+ const {collect} = options; delete options.collect
27
+ assert (collect == null || typeof collect === 'function', 'options.collect must be a function, not ' + typeof collect)
28
+
29
+ const {filter} = options; delete options.filter
30
+ assert (filter == null || typeof filter === 'function', 'options.filter must be a function, not ' + typeof filter)
31
+
32
+ const {map} = options; delete options.map
33
+ assert (map == null || typeof map === 'function', 'options.map must be a function, not ' + typeof map)
34
+
35
+ const {find} = options; delete options.find
36
+ assert (filter == null || find == null, 'filter & find options cannot be set together')
37
+ assert (find == null || typeof find === 'function', 'options.find must be a function, not ' + typeof find)
38
+
18
39
  super (options)
19
40
 
20
- this.stripSpace = options.stripSpace
21
- this.useEntities = options.useEntities
22
-
41
+ this.stripSpace = options.stripSpace
42
+ this.useEntities = options.useEntities
43
+ this.useNamespaces = options.useNamespaces
44
+ this.collect = collect || null
45
+ this.filter = filter || find || null
46
+ this.map = map || null
47
+ this [OPT_ONCE] = find != null
48
+
23
49
  if (this.useEntities) this.entityResolver = new (require ('./EntityResolver.js')) ()
24
50
 
25
51
  this.text = ''
52
+ this.element = null
53
+ this.position = 0n
54
+
55
+ this [OPT_SRC] = null; this.on ('pipe', src => this [OPT_SRC] = src)
56
+
57
+ this [OPT_SAX] = null
26
58
 
27
59
  }
28
60
 
@@ -30,11 +62,50 @@ const XMLReader = class extends Transform {
30
62
 
31
63
  this.flush_text ()
32
64
 
33
- this.push ({type: SAXEvent.TYPES.END_DOCUMENT})
65
+ this.publish ({type: SAXEvent.TYPES.END_DOCUMENT})
34
66
 
35
67
  callback ()
36
68
 
37
69
  }
70
+
71
+ get isSAX () {
72
+
73
+ const v = this [OPT_SAX]; if (v !== null) return v
74
+
75
+ for (const type in SAXEvent.TYPES) if (this.listenerCount (type) !== 0) return this [OPT_SAX] = true
76
+
77
+ return this [OPT_SAX] = false
78
+
79
+ }
80
+
81
+ publish (xmlNode, type = null) {
82
+
83
+ if (type !== null) xmlNode.type = type
84
+
85
+ const {filter} = this; if (filter !== null && !filter (xmlNode)) return
86
+
87
+ const {map} = this, value = map === null ? xmlNode : map (xmlNode)
88
+
89
+ if (this.isSAX) {
90
+
91
+ this.emit (xmlNode.type, value)
92
+
93
+ }
94
+ else {
95
+
96
+ this.push (value)
97
+
98
+ }
99
+
100
+ if (this [OPT_ONCE]) {
101
+
102
+ const src = this [OPT_SRC]; if (src !== null) src.unpipe (this)
103
+
104
+ this.destroy ()
105
+
106
+ }
107
+
108
+ }
38
109
 
39
110
  flush_text () {
40
111
 
@@ -42,41 +113,104 @@ const XMLReader = class extends Transform {
42
113
 
43
114
  if (this.stripSpace) text = text.trim ()
44
115
 
45
- if (text.length !== 0) this.push (new SAXEvent (text))
116
+ if (text.length !== 0) {
117
+
118
+ let e = new XMLNode (text, this, SAXEvent.TYPES.CHARACTERS)
119
+
120
+ e.parent = this.element
121
+
122
+ this.publish (e)
123
+
124
+ }
46
125
 
47
126
  this.text = ''
48
127
 
49
128
  }
129
+
130
+ get fixText () {
131
+
132
+ if (!this.useEntities) return s => s
133
+
134
+ const {entityResolver} = this
135
+
136
+ return s => entityResolver.fix (s)
137
+
138
+ }
50
139
 
51
140
  _transform (chunk, encoding, callback) {
52
141
 
53
- if (chunk.length !== 0) {
142
+ const {length} = chunk; if (length !== 0) {
54
143
 
55
- let e = new SAXEvent (chunk), {type} = e
144
+ let e = new XMLNode (chunk, this), {type} = e, {element} = this
56
145
 
57
146
  switch (type) {
58
147
 
59
148
  case SAXEvent.TYPES.CHARACTERS:
60
-
61
- this.text += this.useEntities ? this.entityResolver.fix (e.text) : e.text
62
- break
63
-
64
149
  case SAXEvent.TYPES.CDATA:
65
150
 
66
151
  this.text += e.text
67
- break
152
+ return callback ()
68
153
 
69
154
  default:
70
155
 
71
156
  this.flush_text ()
72
- this.push (e)
157
+
158
+ }
159
+
160
+ switch (type) {
161
+
162
+ case SAXEvent.TYPES.END_ELEMENT:
163
+
164
+ if (element === null) throw new Error (`Unbalanced end element tag "${chunk}" occured at position ${this.position}`)
165
+
166
+ e = element
167
+
168
+ e.type = type
169
+
170
+ this.element = element.parent
171
+
73
172
  break
74
173
 
174
+ default:
175
+
176
+ e.parent = element
177
+
75
178
  }
76
179
 
77
- if (type === SAXEvent.TYPES.START_ELEMENT && e.isSelfEnclosed) this.push (new SAXEvent ('</>'))
180
+ const isStart = type === SAXEvent.TYPES.START_ELEMENT
78
181
 
79
- }
182
+ if (isStart && this.useNamespaces) e.readNamespaces ()
183
+
184
+ this.publish (e)
185
+
186
+ if (isStart) {
187
+
188
+ if (e.isSelfEnclosed) {
189
+
190
+ this.publish (e, SAXEvent.TYPES.END_ELEMENT)
191
+
192
+ }
193
+ else {
194
+
195
+ if (
196
+
197
+ (this.element !== null && this.element.children !== null)
198
+
199
+ ||
200
+
201
+ (this.collect !== null && this.collect (e))
202
+
203
+ ) e.children = []
204
+
205
+ this.element = e
206
+
207
+ }
208
+
209
+ }
210
+
211
+ this.position += BigInt (length)
212
+
213
+ }
80
214
 
81
215
  callback ()
82
216
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xml-toolkit",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Collection of classes for dealing with XML",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test/soap.xml ADDED
@@ -0,0 +1,40 @@
1
+ <?xml version="1.0"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <SOAP-ENV:Header/>
3
+ <SOAP-ENV:Body>
4
+ <SendRequestRequest xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1" xmlns:ns0="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1">
5
+ <SenderProvidedRequestData Id="Ue7e71ce1-7ce3-4ca5-a689-1a8f2edbb1af">
6
+ <MessageID>3931cda8-3245-11ec-b0bc-000c293433a0</MessageID>
7
+ <ns0:MessagePrimaryContent>
8
+ <ExportDebtRequestsRequest xmlns="urn:dom.gosuslugi.ru/debt-responses/1.0.0" xmlns:ns0="urn:dom.gosuslugi.ru/common/1.2.0">
9
+ <ns0:information-system-id ns0:foo="bar" foo="baz">1f0823b4-9c11-4622-a561-6bae5c0a00ba</ns0:information-system-id>
10
+ <ns0:organization-id>6eef689e-48bb-4eb0-55da-18b6db9909b7</ns0:organization-id>
11
+ <request-id>87c4c940-6ad3-11eb-9439-0242ac130002</request-id>
12
+ </ExportDebtRequestsRequest>
13
+ </ns0:MessagePrimaryContent>
14
+ <TestMessage xmlns:ns1="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1"/>
15
+ </SenderProvidedRequestData>
16
+ <CallerInformationSystemSignature>
17
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
18
+ <ds:SignedInfo>
19
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
20
+ <ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/>
21
+ <ds:Reference URI="#Ue7e71ce1-7ce3-4ca5-a689-1a8f2edbb1af">
22
+ <ds:Transforms>
23
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
24
+ <ds:Transform Algorithm="urn://smev-gov-ru/xmldsig/transform"/>
25
+ </ds:Transforms>
26
+ <ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/>
27
+ <ds:DigestValue>XrXb2BlS8uo68tyQ++KE1yPjj5y3TynCaRIpXeL5uPk=</ds:DigestValue>
28
+ </ds:Reference>
29
+ </ds:SignedInfo>
30
+ <ds:SignatureValue>9Th1waEJy83XQxxKD5DXT29g885RhJoYe3ZQ1HrbrQLCEBchCCTJtcThYmNBPL/HzF2gp7KQs3gXrnsj+OBlJQ==</ds:SignatureValue>
31
+ <ds:KeyInfo>
32
+ <ds:X509Data>
33
+ <ds:X509Certificate>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</ds:X509Certificate>
34
+ </ds:X509Data>
35
+ </ds:KeyInfo>
36
+ </ds:Signature>
37
+ </CallerInformationSystemSignature>
38
+ </SendRequestRequest>
39
+ </SOAP-ENV:Body>
40
+ </SOAP-ENV:Envelope>
package/test/test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const fs = require ('fs')
2
2
  const assert = require ('assert')
3
- const {SAXEventEmitter, SAXEvent, XMLLexer, AttributesMap} = require ('../')
3
+ const {XMLReader, SAXEvent, XMLLexer, AttributesMap, MoxyLikeJsonEncoder} = require ('../')
4
4
 
5
5
  async function test_001_lexer_sync (fn) {
6
6
 
@@ -63,14 +63,22 @@ console.log (xml)
63
63
  // stripSpace: true,
64
64
  })
65
65
 
66
- const sax = new SAXEventEmitter ({
66
+ const sax = new XMLReader ({
67
67
  stripSpace: true,
68
+ collect: e => true,
69
+ find: e => true
70
+ // && e.type === SAXEvent.TYPES.CHARACTERS
71
+ && e.localName === 'SendRequestRequest'
72
+ && e.type === SAXEvent.TYPES.END_ELEMENT
73
+ // && e.level === 6
74
+ ,
75
+ map: MoxyLikeJsonEncoder ({wrap: 1})
68
76
  // useEntities: false,
69
77
  })
70
78
 
71
79
  lex.pipe (sax)
72
80
 
73
- /*
81
+
74
82
  for (let event of [
75
83
  'StartDocument',
76
84
  'ProcessingInstruction',
@@ -80,21 +88,37 @@ console.log (xml)
80
88
  'Characters',
81
89
  'EndElement',
82
90
  'EndDocument',
83
- ]) sax.on (event, data => console.log ([event, data]))
84
- */
85
-
86
- sax.on ('StartElement', event => {
91
+ ]) sax.on (event, data => {
87
92
 
88
- console.log ({event})
93
+ // console.log ([event, data])
89
94
 
90
- const attr = new AttributesMap (sax)
95
+ console.log (JSON.stringify (data, null, 2))
96
+
97
+ /*
98
+ console.log ([event, data, data.name, data.localName, data.namespaceURI])
91
99
 
92
- event.writeAttributesToMap (attr)
100
+ const {attributes} = data; for (const [k, v] of attributes.entries ()) {
93
101
 
94
- console.log ({attr})
102
+ console.log ([k, attributes.getLocalName (k), attributes.getNamespaceURI (k), v])
103
+
104
+ console.log ([attributes.get ('ns0:foo')])
105
+
106
+ console.log ([attributes.get ('foo')])
107
+
108
+ console.log ([attributes.get ('foo', 'urn:dom.gosuslugi.ru/common/1.2.0')])
95
109
 
110
+ }
111
+ */
96
112
  })
113
+
114
+
115
+
97
116
 
117
+ /*
118
+ sax.on ('StartElement', event => {
119
+ console.log ([event, event.attributes])
120
+ })
121
+ */
98
122
  // lexer.on ('data', data => console.log ({data}))
99
123
 
100
124
  // for (let c of xml) lexer.write (c); lexer.end ()
@@ -116,7 +140,8 @@ async function main () {
116
140
  // await test_003_emitter_sync ('E05a.xml')
117
141
  // await test_003_emitter_sync ('param_types.xml')
118
142
  // await test_003_emitter_sync ('not-sa01.xml')
119
- await test_003_emitter_sync ('ent.xml')
143
+ // await test_003_emitter_sync ('ent.xml')
144
+ await test_003_emitter_sync ('soap.xml')
120
145
 
121
146
  }
122
147
 
@@ -1,15 +0,0 @@
1
- const XMLReader = require ('./XMLReader.js')
2
-
3
- const SAXEventEmitter = class extends XMLReader {
4
-
5
- constructor (options = {}) {
6
-
7
- super (options)
8
-
9
- this.on ('data', e => this.emit (e.type, e))
10
-
11
- }
12
-
13
- }
14
-
15
- module.exports = SAXEventEmitter