xml-toolkit 0.0.5 → 0.0.9

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
@@ -3,5 +3,6 @@ const XMLReader = require ('./lib/XMLReader')
3
3
  const SAXEvent = require ('./lib/SAXEvent')
4
4
  const AttributesMap = require ('./lib/AttributesMap')
5
5
  const MoxyLikeJsonEncoder = require ('./lib/MoxyLikeJsonEncoder')
6
+ const XMLNode = require ('./lib/XMLNode')
6
7
 
7
- module.exports = {XMLLexer, XMLReader, SAXEvent, AttributesMap, MoxyLikeJsonEncoder}
8
+ module.exports = {XMLLexer, XMLReader, SAXEvent, AttributesMap, MoxyLikeJsonEncoder, XMLNode}
@@ -65,7 +65,7 @@ const AttributesMap = class extends Map {
65
65
 
66
66
  }
67
67
 
68
- return super.set (k, this.fixText (v))
68
+ return super.set (k, v === '' ? null : this.fixText (v))
69
69
 
70
70
  }
71
71
 
@@ -1,39 +1,63 @@
1
- const SAXEvent = require ('./SAXEvent.js')
1
+ const SAXEvent = require ('./SAXEvent.js'), {CHARACTERS, END_ELEMENT} = SAXEvent.TYPES
2
2
 
3
- const set = (o, k, nv) => {
3
+ const GET_LOCAL_NAME = (localName, namespaceURI) => localName
4
4
 
5
- if (!(k in o)) return o [k] = nv
5
+ const MoxyLikeJsonEncoder = function (options = {}) {
6
6
 
7
- const ov = o [k]; if (!Array.isArray (ov)) o [k] = [ov]
8
-
9
- o [k].push (nv)
7
+ let {getName} = options; if (!getName) getName = GET_LOCAL_NAME
10
8
 
11
- }
9
+ const xform = ({children, attributes}) => {
12
10
 
13
- const xform = ({children, attributes}) => {
11
+ let o = null
14
12
 
15
- let o = attributes == null ? {} : Object.fromEntries (attributes.entries ())
13
+ const set = (nv, localName, namespaceURI) => {
14
+
15
+ const k = getName (localName, namespaceURI)
16
16
 
17
- if (children != null) for (const child of children) switch (child.type) {
17
+ if (o === null) return o = {[k]: nv}
18
18
 
19
- case SAXEvent.TYPES.CHARACTERS: return child.text
19
+ if (!(k in o)) return o [k] = nv
20
20
 
21
- case SAXEvent.TYPES.END_ELEMENT: set (o, child.localName, xform (child))
21
+ const ov = o [k]; if (!Array.isArray (ov)) return o [k] = [ov, nv]
22
22
 
23
- }
24
-
25
- return o
23
+ ov.push (nv)
26
24
 
27
- }
25
+ }
28
26
 
29
- const MoxyLikeJsonEncoder = function (options = {}) {
27
+ if (attributes != null)
28
+
29
+ for (const [name, value] of attributes.entries ())
30
+
31
+ set (value, attributes.getLocalName (name), attributes.getNamespaceURI (name))
32
+
33
+ if (children != null) for (const child of children) switch (child.type) {
34
+
35
+ case CHARACTERS:
36
+
37
+ return child.text
38
+
39
+ case END_ELEMENT:
40
+
41
+ set (xform (child), child.localName, child.namespaceURI)
42
+
43
+ }
44
+
45
+ return o
46
+
47
+ }
30
48
 
31
49
  return function (node) {
32
50
 
33
51
  let result = xform (node)
34
-
35
- return options.wrap ? {[node.localName]: result} : result
36
-
52
+
53
+ const {wrap, map} = options
54
+
55
+ if (wrap) result = {[getName (node.localName, node.namespaceURI)]: result}
56
+
57
+ if (map) result = map (result)
58
+
59
+ return result
60
+
37
61
  }
38
62
 
39
63
  }
package/lib/SAXEvent.js CHANGED
@@ -96,6 +96,20 @@ const SAXEvent = class {
96
96
  }
97
97
 
98
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
+ }
99
113
 
100
114
  get attributes () {
101
115
 
@@ -182,6 +196,24 @@ const SAXEvent = class {
182
196
 
183
197
  }
184
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
+
185
217
  }
186
218
 
187
219
  SAXEvent.TYPES = {
package/lib/XMLNode.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const SAXEvent = require ('./SAXEvent.js')
2
2
  const AttributesMap = require ('./AttributesMap')
3
3
  const NamespacesMap = require ('./NamespacesMap')
4
+ const MoxyLikeJsonEncoder = require ('./MoxyLikeJsonEncoder')
4
5
 
5
6
  const XML_READER = Symbol ('_xmlReader')
6
7
  const ATTRIBUTES = Symbol ('_attributes')
@@ -25,6 +26,20 @@ const XMLNode = class extends SAXEvent {
25
26
 
26
27
  }
27
28
 
29
+ cloneStart () {
30
+
31
+ let e = new XMLNode (this.src, this [XML_READER], SAXEvent.TYPES.START_ELEMENT)
32
+
33
+ e [PARENT] = this [PARENT]
34
+ e [LEVEL] = this [LEVEL]
35
+
36
+ if (ATTRIBUTES in this) e [ATTRIBUTES] = this [ATTRIBUTES]
37
+ if (NS_MAP in this) e [NS_MAP] = this [NS_MAP]
38
+
39
+ return e
40
+
41
+ }
42
+
28
43
  get level () {
29
44
 
30
45
  return this [LEVEL]
@@ -83,7 +98,9 @@ const XMLNode = class extends SAXEvent {
83
98
 
84
99
  get namespaceURI () {
85
100
 
86
- return this.namespacesMap.getNamespaceURI (this.name, true)
101
+ const {namespacesMap} = this; if (namespacesMap == null) return null
102
+
103
+ return namespacesMap.getNamespaceURI (this.name, true)
87
104
 
88
105
  }
89
106
 
@@ -125,4 +142,6 @@ XMLNode.getLocalName = name => {
125
142
 
126
143
  }
127
144
 
145
+ XMLNode.toObject = MoxyLikeJsonEncoder
146
+
128
147
  module.exports = XMLNode
package/lib/XMLReader.js CHANGED
@@ -14,7 +14,7 @@ const XMLReader = class extends Transform {
14
14
  options.decodeStrings = false
15
15
  options.objectMode = true
16
16
 
17
- if (!('stripSpace' in options)) options.stripSpace = false
17
+ if (!('stripSpace' in options)) options.stripSpace = ('filterElements' in options)
18
18
  assert (options.stripSpace === true || options.stripSpace === false, 'options.stripSpace must be boolean, not ' + typeof options.stripSpace)
19
19
 
20
20
  if (!('useEntities' in options)) options.useEntities = true
@@ -123,7 +123,7 @@ const XMLReader = class extends Transform {
123
123
 
124
124
  this.flush_text ()
125
125
 
126
- this.publish ({type: SAXEvent.TYPES.END_DOCUMENT})
126
+ this.publish (new XMLNode ('', this), SAXEvent.TYPES.END_DOCUMENT)
127
127
 
128
128
  callback ()
129
129
 
@@ -234,7 +234,7 @@ const XMLReader = class extends Transform {
234
234
 
235
235
  if (isStart && this.useNamespaces) e.readNamespaces ()
236
236
 
237
- this.publish (e)
237
+ this.publish (isStart ? e.cloneStart () : e)
238
238
 
239
239
  if (isStart) {
240
240
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xml-toolkit",
3
- "version": "0.0.5",
3
+ "version": "0.0.9",
4
4
  "description": "Collection of classes for dealing with XML",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test/soap.xml CHANGED
@@ -2,7 +2,7 @@
2
2
  <SOAP-ENV:Header/>
3
3
  <SOAP-ENV:Body>
4
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">
5
+ <SenderProvidedRequestData Id="Ue7e71ce1-7ce3-4ca5-a689-1a8f2edbb1af" IDDQD="">
6
6
  <MessageID>3931cda8-3245-11ec-b0bc-000c293433a0</MessageID>
7
7
  <ns0:MessagePrimaryContent>
8
8
  <ExportDebtRequestsRequest xmlns="urn:dom.gosuslugi.ru/debt-responses/1.0.0" xmlns:ns0="urn:dom.gosuslugi.ru/common/1.2.0">
package/test/test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const fs = require ('fs')
2
2
  const assert = require ('assert')
3
- const {XMLReader, SAXEvent, XMLLexer, AttributesMap, MoxyLikeJsonEncoder} = require ('../')
3
+ const {XMLReader, SAXEvent, XMLLexer, AttributesMap, XMLNode} = require ('../')
4
4
 
5
5
  async function test_001_lexer_sync (fn) {
6
6
 
@@ -52,15 +52,19 @@ async function test_003_emitter_sync (fn) {
52
52
 
53
53
  const xml = fs.readFileSync (
54
54
  'test/' + fn
55
- // , 'utf-8'
55
+ , 'utf-8'
56
56
  )
57
57
 
58
58
  console.log (xml)
59
59
 
60
60
  const sax = new XMLReader ({
61
- stripSpace: true,
61
+ // stripSpace: true,
62
62
  filterElements: 'SendRequestRequest',
63
- map: MoxyLikeJsonEncoder ({wrap: 1})
63
+ map: XMLNode.toObject ({
64
+ // wrap: 1,
65
+ getName: (localName, namespaceURI) => (!namespaceURI ? '' : '{' + namespaceURI + '}') + localName,
66
+ map: o => Object.fromEntries (Object.entries (o).map (([k, v]) => [k + '111', v]))
67
+ })
64
68
  })
65
69
 
66
70
  /*
@@ -77,21 +81,20 @@ console.log (xml)
77
81
  })
78
82
  */
79
83
 
80
-
81
- // sax.process (fs.createReadStream ('test/' + fn))
82
-
83
- sax.process (xml)
84
-
84
+
85
85
  //console.log (sax)
86
86
  //console.log (sax.isSAX)
87
87
 
88
88
  /*
89
+ let s = ''
89
90
  for await (const e of sax) {
90
- console.log (e)
91
+ s += xml
92
+ // console.log ([e.type, e.isStartElement, e.isEndElement , e.isCharacters])
91
93
  }
92
94
  */
95
+ //console.log ([xml, s])
93
96
 
94
- const v = await sax.findFirst ()
97
+ const v = await sax.process (xml).findFirst ()
95
98
 
96
99
  console.log (JSON.stringify (v, null, 2))
97
100