xml-toolkit 0.0.3 → 0.0.7
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 +6 -5
- package/lib/AttributesMap.js +53 -16
- package/lib/MoxyLikeJsonEncoder.js +41 -0
- package/lib/NamespacesMap.js +48 -0
- package/lib/SAXEvent.js +66 -1
- package/lib/XMLNode.js +141 -0
- package/lib/XMLReader.js +202 -15
- package/package.json +1 -1
- package/test/soap.xml +40 -0
- package/test/test.js +34 -37
- package/lib/SAXEventEmitter.js +0 -15
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
const XMLLexer
|
|
2
|
-
const
|
|
3
|
-
const SAXEvent
|
|
4
|
-
const 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 = {
|
|
7
|
+
module.exports = {XMLLexer, XMLReader, SAXEvent, AttributesMap, MoxyLikeJsonEncoder}
|
package/lib/AttributesMap.js
CHANGED
|
@@ -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.
|
|
10
|
-
|
|
11
|
-
if (xmlReader.useEntities) {
|
|
32
|
+
for (const k of this._nsMap.getQNames (name, namespaceURI)) {
|
|
12
33
|
|
|
13
|
-
|
|
34
|
+
if (!this.has (k)) continue
|
|
14
35
|
|
|
15
|
-
this.
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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 = attributes == null ? {} : 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).
|
|
50
|
+
switch (src.slice (2, 5).toUpperCase ()) {
|
|
50
51
|
|
|
51
52
|
case STR_XML: return START_DOCUMENT
|
|
52
53
|
|
|
@@ -95,6 +96,20 @@ const SAXEvent = class {
|
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
}
|
|
99
|
+
|
|
100
|
+
get xml () {
|
|
101
|
+
|
|
102
|
+
switch (this.type) {
|
|
103
|
+
|
|
104
|
+
case END_DOCUMENT: return ''
|
|
105
|
+
|
|
106
|
+
case END_ELEMENT: return this.isSelfEnclosed ? '' : `</${this.name}>`
|
|
107
|
+
|
|
108
|
+
default: return this.src
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
}
|
|
98
113
|
|
|
99
114
|
get attributes () {
|
|
100
115
|
|
|
@@ -106,6 +121,38 @@ const SAXEvent = class {
|
|
|
106
121
|
|
|
107
122
|
}
|
|
108
123
|
|
|
124
|
+
get name () {
|
|
125
|
+
|
|
126
|
+
if (this._afterName === 0) this.findAfterName ()
|
|
127
|
+
|
|
128
|
+
const {src} = this, start = src.charCodeAt (1) === CH_SLASH ? 2 : 1
|
|
129
|
+
|
|
130
|
+
return this.src.slice (start, this._afterName).trim ()
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
findAfterName () {
|
|
135
|
+
|
|
136
|
+
const {src} = this, {length} = src;
|
|
137
|
+
|
|
138
|
+
for (let i = 1; i < length; i ++) {
|
|
139
|
+
|
|
140
|
+
const c = src.charCodeAt (i)
|
|
141
|
+
|
|
142
|
+
switch (c) {
|
|
143
|
+
case CH_SLASH:
|
|
144
|
+
case CH_GT:
|
|
145
|
+
return this._afterName = i
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (c <= 32) return this._afterName = i
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this._afterName = length - 1
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
109
156
|
writeAttributesToMap (m) {
|
|
110
157
|
|
|
111
158
|
const {src} = this
|
|
@@ -149,6 +196,24 @@ const SAXEvent = class {
|
|
|
149
196
|
|
|
150
197
|
}
|
|
151
198
|
|
|
199
|
+
get isStartElement () {
|
|
200
|
+
|
|
201
|
+
return this.type === START_ELEMENT
|
|
202
|
+
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
get isEndElement () {
|
|
206
|
+
|
|
207
|
+
return this.type === END_ELEMENT
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
get isCharacters () {
|
|
212
|
+
|
|
213
|
+
return this.type === CHARACTERS
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
152
217
|
}
|
|
153
218
|
|
|
154
219
|
SAXEvent.TYPES = {
|
package/lib/XMLNode.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
cloneStart () {
|
|
29
|
+
|
|
30
|
+
let e = new XMLNode (this.src, this [XML_READER], SAXEvent.TYPES.START_ELEMENT)
|
|
31
|
+
|
|
32
|
+
e [PARENT] = this [PARENT]
|
|
33
|
+
e [LEVEL] = this [LEVEL]
|
|
34
|
+
e [ATTRIBUTES] = this [ATTRIBUTES]
|
|
35
|
+
e [NS_MAP] = this [NS_MAP]
|
|
36
|
+
|
|
37
|
+
return e
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get level () {
|
|
42
|
+
|
|
43
|
+
return this [LEVEL]
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get parent () {
|
|
48
|
+
|
|
49
|
+
return this [PARENT]
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get namespacesMap () {
|
|
54
|
+
|
|
55
|
+
return this [NS_MAP]
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
readNamespaces () {
|
|
60
|
+
|
|
61
|
+
this [NS_MAP] = new NamespacesMap (this)
|
|
62
|
+
|
|
63
|
+
this.readAttributes ()
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
set parent (_parent) {
|
|
68
|
+
|
|
69
|
+
if (_parent == null) return
|
|
70
|
+
|
|
71
|
+
this [PARENT] = _parent
|
|
72
|
+
|
|
73
|
+
this [LEVEL] = 1 + _parent.level
|
|
74
|
+
|
|
75
|
+
const {children} = _parent; if (children !== null) children.push (this)
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
get type () {
|
|
80
|
+
|
|
81
|
+
return this [TYPE]
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
set type (_type) {
|
|
86
|
+
|
|
87
|
+
this [TYPE] = _type
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get localName () {
|
|
92
|
+
|
|
93
|
+
return XMLNode.getLocalName (this.name)
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
get namespaceURI () {
|
|
98
|
+
|
|
99
|
+
return this.namespacesMap.getNamespaceURI (this.name, true)
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
readAttributes () {
|
|
104
|
+
|
|
105
|
+
const m = new AttributesMap (this [XML_READER], this [NS_MAP])
|
|
106
|
+
|
|
107
|
+
this.writeAttributesToMap (m)
|
|
108
|
+
|
|
109
|
+
this [ATTRIBUTES] = m
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
get attributes () {
|
|
114
|
+
|
|
115
|
+
if (!(ATTRIBUTES in this)) this.readAttributes ()
|
|
116
|
+
|
|
117
|
+
return this [ATTRIBUTES]
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get text () {
|
|
122
|
+
|
|
123
|
+
let s = super.text
|
|
124
|
+
|
|
125
|
+
if (this [TYPE] === SAXEvent.TYPES.CHARACTERS) s = this [XML_READER].fixText (s)
|
|
126
|
+
|
|
127
|
+
return s
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
XMLNode.getLocalName = name => {
|
|
134
|
+
|
|
135
|
+
const pos = name.indexOf (':'); if (pos === -1) return name
|
|
136
|
+
|
|
137
|
+
return name.slice (pos + 1)
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
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
|
+
const XMLLexer = require ('./XMLLexer.js')
|
|
6
|
+
|
|
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,102 @@ 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
|
|
|
18
|
-
|
|
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
|
+
let {filterElements} = options; delete options.filterElements; if (filterElements != null) {
|
|
27
|
+
|
|
28
|
+
assert (!('filter' in options), 'filter and filterElements options cannot be set simultaneously')
|
|
29
|
+
|
|
30
|
+
switch (typeof filterElements) {
|
|
31
|
+
|
|
32
|
+
case 'string':
|
|
33
|
+
const localName = filterElements
|
|
34
|
+
filterElements = e => e.localName === localName
|
|
35
|
+
|
|
36
|
+
case 'function':
|
|
37
|
+
options.filter = e => e.type === SAXEvent.TYPES.END_ELEMENT && filterElements (e)
|
|
38
|
+
break
|
|
39
|
+
|
|
40
|
+
default:
|
|
41
|
+
assert.fail ('options.filterElements must be a string or function')
|
|
19
42
|
|
|
20
|
-
|
|
21
|
-
this.useEntities = options.useEntities
|
|
43
|
+
}
|
|
22
44
|
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let {collect} = options; delete options.collect
|
|
48
|
+
assert (collect == null || typeof collect === 'function', 'options.collect must be a function, not ' + typeof collect)
|
|
49
|
+
if (collect == null && filterElements != null) collect = filterElements
|
|
50
|
+
|
|
51
|
+
const {filter} = options; delete options.filter
|
|
52
|
+
assert (filter == null || typeof filter === 'function', 'options.filter must be a function, not ' + typeof filter)
|
|
53
|
+
|
|
54
|
+
const {map} = options; delete options.map
|
|
55
|
+
assert (map == null || typeof map === 'function', 'options.map must be a function, not ' + typeof map)
|
|
56
|
+
|
|
57
|
+
super (options)
|
|
58
|
+
|
|
59
|
+
this.stripSpace = options.stripSpace
|
|
60
|
+
this.useEntities = options.useEntities
|
|
61
|
+
this.useNamespaces = options.useNamespaces
|
|
62
|
+
this.collect = collect || null
|
|
63
|
+
this.filter = filter || null
|
|
64
|
+
this.map = map || null
|
|
65
|
+
|
|
23
66
|
if (this.useEntities) this.entityResolver = new (require ('./EntityResolver.js')) ()
|
|
24
67
|
|
|
25
68
|
this.text = ''
|
|
69
|
+
this.element = null
|
|
70
|
+
this.position = 0n
|
|
71
|
+
|
|
72
|
+
this [OPT_SRC] = null; this.on ('pipe', src => this [OPT_SRC] = src)
|
|
73
|
+
|
|
74
|
+
this [OPT_SAX] = null
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async findFirst () {
|
|
79
|
+
|
|
80
|
+
assert (!this.isSAX, 'SAX event subscriber detected, findFirst () cannot be used')
|
|
81
|
+
|
|
82
|
+
return new Promise ((ok, fail) => {
|
|
83
|
+
|
|
84
|
+
this.once ('error', fail)
|
|
85
|
+
|
|
86
|
+
const THE_END = 'finish', nope = () => ok (null)
|
|
87
|
+
|
|
88
|
+
this.on (THE_END, nope)
|
|
89
|
+
|
|
90
|
+
this.on ('data', e => {
|
|
91
|
+
|
|
92
|
+
this.off (THE_END, nope)
|
|
93
|
+
|
|
94
|
+
if (e.type === SAXEvent.TYPES.END_DOCUMENT) return nope ()
|
|
95
|
+
|
|
96
|
+
const src = this [OPT_SRC]; if (src !== null) src.unpipe (this)
|
|
97
|
+
|
|
98
|
+
ok (e)
|
|
99
|
+
|
|
100
|
+
this.destroy ()
|
|
101
|
+
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
process (src, lexerOptions = {}) {
|
|
109
|
+
|
|
110
|
+
const lex = new XMLLexer (lexerOptions)
|
|
111
|
+
|
|
112
|
+
lex.once ('error', x => this.destroy (x))
|
|
113
|
+
|
|
114
|
+
lex.pipe (this)
|
|
115
|
+
|
|
116
|
+
if (Buffer.isBuffer (src) || typeof src === 'string') lex.end (src); else src.pipe (lex)
|
|
117
|
+
|
|
118
|
+
return this
|
|
26
119
|
|
|
27
120
|
}
|
|
28
121
|
|
|
@@ -30,11 +123,42 @@ const XMLReader = class extends Transform {
|
|
|
30
123
|
|
|
31
124
|
this.flush_text ()
|
|
32
125
|
|
|
33
|
-
this.
|
|
126
|
+
this.publish (new XMLNode ('', this), SAXEvent.TYPES.END_DOCUMENT)
|
|
34
127
|
|
|
35
128
|
callback ()
|
|
36
129
|
|
|
37
130
|
}
|
|
131
|
+
|
|
132
|
+
get isSAX () {
|
|
133
|
+
|
|
134
|
+
const v = this [OPT_SAX]; if (v !== null) return v
|
|
135
|
+
|
|
136
|
+
for (const type of Object.values (SAXEvent.TYPES)) if (this.listenerCount (type) !== 0) return this [OPT_SAX] = true
|
|
137
|
+
|
|
138
|
+
return this [OPT_SAX] = false
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
publish (xmlNode, type = null) {
|
|
143
|
+
|
|
144
|
+
if (type !== null) xmlNode.type = type
|
|
145
|
+
|
|
146
|
+
const {filter} = this; if (filter !== null && !filter (xmlNode)) return
|
|
147
|
+
|
|
148
|
+
const {map} = this, value = map === null ? xmlNode : map (xmlNode)
|
|
149
|
+
|
|
150
|
+
if (this.isSAX) {
|
|
151
|
+
|
|
152
|
+
this.emit (xmlNode.type, value)
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
|
|
157
|
+
this.push (value)
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
}
|
|
38
162
|
|
|
39
163
|
flush_text () {
|
|
40
164
|
|
|
@@ -42,41 +166,104 @@ const XMLReader = class extends Transform {
|
|
|
42
166
|
|
|
43
167
|
if (this.stripSpace) text = text.trim ()
|
|
44
168
|
|
|
45
|
-
if (text.length !== 0)
|
|
169
|
+
if (text.length !== 0) {
|
|
170
|
+
|
|
171
|
+
let e = new XMLNode (text, this, SAXEvent.TYPES.CHARACTERS)
|
|
172
|
+
|
|
173
|
+
e.parent = this.element
|
|
174
|
+
|
|
175
|
+
this.publish (e)
|
|
176
|
+
|
|
177
|
+
}
|
|
46
178
|
|
|
47
179
|
this.text = ''
|
|
48
180
|
|
|
49
181
|
}
|
|
182
|
+
|
|
183
|
+
get fixText () {
|
|
184
|
+
|
|
185
|
+
if (!this.useEntities) return s => s
|
|
186
|
+
|
|
187
|
+
const {entityResolver} = this
|
|
188
|
+
|
|
189
|
+
return s => entityResolver.fix (s)
|
|
190
|
+
|
|
191
|
+
}
|
|
50
192
|
|
|
51
193
|
_transform (chunk, encoding, callback) {
|
|
52
194
|
|
|
53
|
-
if (
|
|
195
|
+
const {length} = chunk; if (length !== 0) {
|
|
54
196
|
|
|
55
|
-
let e = new
|
|
197
|
+
let e = new XMLNode (chunk, this), {type} = e, {element} = this
|
|
56
198
|
|
|
57
199
|
switch (type) {
|
|
58
200
|
|
|
59
201
|
case SAXEvent.TYPES.CHARACTERS:
|
|
60
|
-
|
|
61
|
-
this.text += this.useEntities ? this.entityResolver.fix (e.text) : e.text
|
|
62
|
-
break
|
|
63
|
-
|
|
64
202
|
case SAXEvent.TYPES.CDATA:
|
|
65
203
|
|
|
66
204
|
this.text += e.text
|
|
67
|
-
|
|
205
|
+
return callback ()
|
|
68
206
|
|
|
69
207
|
default:
|
|
70
208
|
|
|
71
209
|
this.flush_text ()
|
|
72
|
-
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
switch (type) {
|
|
214
|
+
|
|
215
|
+
case SAXEvent.TYPES.END_ELEMENT:
|
|
216
|
+
|
|
217
|
+
if (element === null) throw new Error (`Unbalanced end element tag "${chunk}" occured at position ${this.position}`)
|
|
218
|
+
|
|
219
|
+
e = element
|
|
220
|
+
|
|
221
|
+
e.type = type
|
|
222
|
+
|
|
223
|
+
this.element = element.parent
|
|
224
|
+
|
|
73
225
|
break
|
|
74
226
|
|
|
227
|
+
default:
|
|
228
|
+
|
|
229
|
+
e.parent = element
|
|
230
|
+
|
|
75
231
|
}
|
|
76
232
|
|
|
77
|
-
|
|
233
|
+
const isStart = type === SAXEvent.TYPES.START_ELEMENT
|
|
78
234
|
|
|
79
|
-
|
|
235
|
+
if (isStart && this.useNamespaces) e.readNamespaces ()
|
|
236
|
+
|
|
237
|
+
this.publish (isStart ? e.cloneStart () : e)
|
|
238
|
+
|
|
239
|
+
if (isStart) {
|
|
240
|
+
|
|
241
|
+
if (e.isSelfEnclosed) {
|
|
242
|
+
|
|
243
|
+
this.publish (e, SAXEvent.TYPES.END_ELEMENT)
|
|
244
|
+
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
|
|
248
|
+
if (
|
|
249
|
+
|
|
250
|
+
(this.element !== null && this.element.children !== null)
|
|
251
|
+
|
|
252
|
+
||
|
|
253
|
+
|
|
254
|
+
(this.collect !== null && this.collect (e))
|
|
255
|
+
|
|
256
|
+
) e.children = []
|
|
257
|
+
|
|
258
|
+
this.element = e
|
|
259
|
+
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
this.position += BigInt (length)
|
|
265
|
+
|
|
266
|
+
}
|
|
80
267
|
|
|
81
268
|
callback ()
|
|
82
269
|
|
package/package.json
CHANGED
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 {
|
|
3
|
+
const {XMLReader, SAXEvent, XMLLexer, AttributesMap, MoxyLikeJsonEncoder} = require ('../')
|
|
4
4
|
|
|
5
5
|
async function test_001_lexer_sync (fn) {
|
|
6
6
|
|
|
@@ -52,55 +52,51 @@ async function test_003_emitter_sync (fn) {
|
|
|
52
52
|
|
|
53
53
|
const xml = fs.readFileSync (
|
|
54
54
|
'test/' + fn
|
|
55
|
-
|
|
55
|
+
, 'utf-8'
|
|
56
56
|
)
|
|
57
57
|
|
|
58
58
|
console.log (xml)
|
|
59
59
|
|
|
60
|
-
const
|
|
61
|
-
// maxLength: 40,
|
|
62
|
-
// encoding: 'ascii',
|
|
60
|
+
const sax = new XMLReader ({
|
|
63
61
|
// stripSpace: true,
|
|
62
|
+
// filterElements: 'SendRequestRequest',
|
|
63
|
+
// map: MoxyLikeJsonEncoder ({wrap: 1})
|
|
64
64
|
})
|
|
65
65
|
|
|
66
|
-
const sax = new SAXEventEmitter ({
|
|
67
|
-
stripSpace: true,
|
|
68
|
-
// useEntities: false,
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
lex.pipe (sax)
|
|
72
|
-
|
|
73
66
|
/*
|
|
74
67
|
for (let event of [
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
]) sax.on (event, data => console.log ([event, data]))
|
|
84
|
-
*/
|
|
85
|
-
|
|
86
|
-
sax.on ('StartElement', event => {
|
|
68
|
+
'data',
|
|
69
|
+
'close',
|
|
70
|
+
'end',
|
|
71
|
+
'finish',
|
|
72
|
+
// 'EndElement',
|
|
73
|
+
]) sax.on (event, data => {
|
|
74
|
+
|
|
75
|
+
console.log ([JSON.stringify (data, null, 2), event])
|
|
87
76
|
|
|
88
|
-
console.log ({event})
|
|
89
|
-
|
|
90
|
-
const attr = new AttributesMap (sax)
|
|
91
|
-
|
|
92
|
-
event.writeAttributesToMap (attr)
|
|
93
|
-
|
|
94
|
-
console.log ({attr})
|
|
95
|
-
|
|
96
77
|
})
|
|
78
|
+
*/
|
|
97
79
|
|
|
98
|
-
// lexer.on ('data', data => console.log ({data}))
|
|
99
80
|
|
|
100
|
-
//
|
|
101
|
-
|
|
81
|
+
// sax.process (fs.createReadStream ('test/' + fn))
|
|
82
|
+
|
|
83
|
+
sax.process (xml)
|
|
84
|
+
|
|
85
|
+
//console.log (sax)
|
|
86
|
+
//console.log (sax.isSAX)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
let s = ''
|
|
90
|
+
for await (const e of sax) {
|
|
91
|
+
// s += xml
|
|
92
|
+
console.log ([e.type, e.isStartElement, e.isEndElement , e.isCharacters])
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//console.log ([xml, s])
|
|
96
|
+
|
|
97
|
+
// const v = await sax.findFirst ()
|
|
102
98
|
|
|
103
|
-
|
|
99
|
+
// console.log (JSON.stringify (v, null, 2))
|
|
104
100
|
|
|
105
101
|
}
|
|
106
102
|
|
|
@@ -116,7 +112,8 @@ async function main () {
|
|
|
116
112
|
// await test_003_emitter_sync ('E05a.xml')
|
|
117
113
|
// await test_003_emitter_sync ('param_types.xml')
|
|
118
114
|
// await test_003_emitter_sync ('not-sa01.xml')
|
|
119
|
-
await test_003_emitter_sync ('ent.xml')
|
|
115
|
+
// await test_003_emitter_sync ('ent.xml')
|
|
116
|
+
await test_003_emitter_sync ('soap.xml')
|
|
120
117
|
|
|
121
118
|
}
|
|
122
119
|
|
package/lib/SAXEventEmitter.js
DELETED
|
@@ -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
|