xml-toolkit 1.1.0 → 1.1.2
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/NamespacesMap.js +2 -0
- package/lib/XMLIterator.js +22 -0
- package/lib/XMLParser.js +3 -3
- package/lib/XMLReader.js +28 -4
- package/lib/XSAnyType.js +1 -1
- package/lib/validation/XMLValidationState.js +16 -6
- package/package.json +1 -1
package/lib/NamespacesMap.js
CHANGED
|
@@ -2,6 +2,7 @@ const CH_COLON = ':'.charCodeAt (0)
|
|
|
2
2
|
|
|
3
3
|
const XMLNamespace = 'http://www.w3.org/XML/1998/namespace'
|
|
4
4
|
const XMLNamespacePrefix = 'xml'
|
|
5
|
+
const XSINamespace = 'http://www.w3.org/2001/XMLSchema-instance'
|
|
5
6
|
|
|
6
7
|
const DEFAULTS = [
|
|
7
8
|
[XMLNamespacePrefix, XMLNamespace],
|
|
@@ -75,5 +76,6 @@ const NamespacesMap = class extends Map {
|
|
|
75
76
|
|
|
76
77
|
NamespacesMap.XMLNamespace = XMLNamespace
|
|
77
78
|
NamespacesMap.XMLNamespacePrefix = XMLNamespacePrefix
|
|
79
|
+
NamespacesMap.XSINamespace = XSINamespace
|
|
78
80
|
|
|
79
81
|
module.exports = NamespacesMap
|
package/lib/XMLIterator.js
CHANGED
|
@@ -2,6 +2,8 @@ const XMLNode = require ('./XMLNode.js')
|
|
|
2
2
|
const SAXEvent = require ('./SAXEvent.js')
|
|
3
3
|
const EntityResolver = require ('./EntityResolver.js')
|
|
4
4
|
|
|
5
|
+
const CH_LF = '\n'.charCodeAt (0)
|
|
6
|
+
|
|
5
7
|
const XMLIterator = class {
|
|
6
8
|
|
|
7
9
|
constructor (src, options = {}) {
|
|
@@ -30,6 +32,26 @@ const XMLIterator = class {
|
|
|
30
32
|
|
|
31
33
|
}
|
|
32
34
|
|
|
35
|
+
get linePos () {
|
|
36
|
+
|
|
37
|
+
const {pos} = this
|
|
38
|
+
|
|
39
|
+
let l = 1, c = -1
|
|
40
|
+
|
|
41
|
+
for (let i = pos; i >= 0; i --) {
|
|
42
|
+
|
|
43
|
+
if (this.src.charCodeAt (i) !== CH_LF) continue
|
|
44
|
+
|
|
45
|
+
l ++; if (c !== -1) continue
|
|
46
|
+
|
|
47
|
+
c = pos - i
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return [l, c]
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
33
55
|
next () {
|
|
34
56
|
|
|
35
57
|
if (this.selfEnclosed !== null) return this.autoClose ()
|
package/lib/XMLParser.js
CHANGED
|
@@ -41,7 +41,7 @@ const XMLParser = class {
|
|
|
41
41
|
|
|
42
42
|
if (this.useEntities) this.entityResolver = new (require ('./EntityResolver.js')) ()
|
|
43
43
|
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
|
|
46
46
|
process (src) {
|
|
47
47
|
|
|
@@ -84,7 +84,7 @@ const XMLParser = class {
|
|
|
84
84
|
this.element = node
|
|
85
85
|
if (this.document === null) {
|
|
86
86
|
this.document = node
|
|
87
|
-
if (this.xs !== null) this.validator = new XMLValidatior (this.xs, node, () => nodes.
|
|
87
|
+
if (this.xs !== null) this.validator = new XMLValidatior (this.xs, node, () => nodes.linePos)
|
|
88
88
|
}
|
|
89
89
|
else {
|
|
90
90
|
if (this.xs !== null) this.validator.startElement (node)
|
|
@@ -93,7 +93,7 @@ const XMLParser = class {
|
|
|
93
93
|
|
|
94
94
|
case SAXEvent.TYPES.END_ELEMENT:
|
|
95
95
|
|
|
96
|
-
if (this.element === null) throw new Error (`Unbalanced end element tag "${node.
|
|
96
|
+
if (this.element === null) throw new Error (`Unbalanced end element tag "${node.src}" occured at position ${nodes.pos}`)
|
|
97
97
|
node ['_ns_map'] = this.element ['_ns_map']
|
|
98
98
|
this.element.type = type
|
|
99
99
|
this.element = this.element.parent
|
package/lib/XMLReader.js
CHANGED
|
@@ -10,6 +10,8 @@ const OPT_SAX = Symbol ('_sax')
|
|
|
10
10
|
|
|
11
11
|
const NO_CHILDREN = []; NO_CHILDREN.push = () => {}
|
|
12
12
|
|
|
13
|
+
const CH_LF = '\n'.charCodeAt (0)
|
|
14
|
+
|
|
13
15
|
const XMLReader = class extends Transform {
|
|
14
16
|
|
|
15
17
|
constructor (options = {}) {
|
|
@@ -68,12 +70,16 @@ const XMLReader = class extends Transform {
|
|
|
68
70
|
this.useNamespaces = options.useNamespaces
|
|
69
71
|
this.filter = filter || null
|
|
70
72
|
this.map = map || null
|
|
73
|
+
|
|
74
|
+
this.lineNo = 1
|
|
75
|
+
this.lineStart = 0
|
|
71
76
|
|
|
72
77
|
if (this.useEntities) this.entityResolver = new (require ('./EntityResolver.js')) ()
|
|
73
78
|
|
|
74
79
|
this.text = ''
|
|
75
80
|
this.element = null
|
|
76
|
-
this.position =
|
|
81
|
+
this.position = 0
|
|
82
|
+
this.pos = 0 // TODO: cleanup
|
|
77
83
|
|
|
78
84
|
this [OPT_SRC] = null; this.on ('pipe', src => this [OPT_SRC] = src)
|
|
79
85
|
|
|
@@ -111,7 +117,7 @@ const XMLReader = class extends Transform {
|
|
|
111
117
|
|
|
112
118
|
process (src, lexerOptions = {}) {
|
|
113
119
|
|
|
114
|
-
const lex = new XMLLexer (lexerOptions)
|
|
120
|
+
const lex = this.lex = new XMLLexer (lexerOptions)
|
|
115
121
|
|
|
116
122
|
lex.once ('error', x => this.destroy (x))
|
|
117
123
|
|
|
@@ -148,7 +154,7 @@ const XMLReader = class extends Transform {
|
|
|
148
154
|
if (!this.validator) switch (xmlNode.type) {
|
|
149
155
|
|
|
150
156
|
case SAXEvent.TYPES.START_ELEMENT:
|
|
151
|
-
this.validator = new XMLValidatior (this.xs, xmlNode, () => this.
|
|
157
|
+
this.validator = new XMLValidatior (this.xs, xmlNode, () => this.linePos)
|
|
152
158
|
|
|
153
159
|
default:
|
|
154
160
|
return
|
|
@@ -244,10 +250,28 @@ const XMLReader = class extends Transform {
|
|
|
244
250
|
|
|
245
251
|
}
|
|
246
252
|
|
|
253
|
+
get linePos () {
|
|
254
|
+
|
|
255
|
+
return [this.lineNo, this.pos - this.lineStart]
|
|
256
|
+
|
|
257
|
+
}
|
|
258
|
+
|
|
247
259
|
_transform (chunk, encoding, callback) {
|
|
248
260
|
|
|
249
261
|
const {length} = chunk; if (length !== 0) {
|
|
250
262
|
|
|
263
|
+
for (let i = 0; i < length; i ++) {
|
|
264
|
+
|
|
265
|
+
this.pos ++
|
|
266
|
+
|
|
267
|
+
if (chunk.charCodeAt (i) !== CH_LF) continue
|
|
268
|
+
|
|
269
|
+
this.lineNo ++
|
|
270
|
+
|
|
271
|
+
this.lineStart = this.pos
|
|
272
|
+
|
|
273
|
+
}
|
|
274
|
+
|
|
251
275
|
let e = new XMLNode (chunk, this.entityResolver), {type} = e, {element} = this
|
|
252
276
|
|
|
253
277
|
switch (type) {
|
|
@@ -310,7 +334,7 @@ const XMLReader = class extends Transform {
|
|
|
310
334
|
|
|
311
335
|
}
|
|
312
336
|
|
|
313
|
-
this.position +=
|
|
337
|
+
this.position += length
|
|
314
338
|
|
|
315
339
|
}
|
|
316
340
|
|
package/lib/XSAnyType.js
CHANGED
|
@@ -37,7 +37,7 @@ module.exports = class {
|
|
|
37
37
|
|
|
38
38
|
this.elements = this.#parent.elements.concat (this.elements)
|
|
39
39
|
|
|
40
|
-
this.content = new Occurable ([this.#parent.content, this.content])
|
|
40
|
+
this.content = new Occurable ([this.#parent.content, this.content].filter (Boolean))
|
|
41
41
|
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const {XSINamespace} = require ('../NamespacesMap')
|
|
2
|
+
|
|
1
3
|
class XMLValidationState {
|
|
2
4
|
|
|
3
5
|
#child = null
|
|
@@ -15,7 +17,7 @@ class XMLValidationState {
|
|
|
15
17
|
}
|
|
16
18
|
catch (cause) {
|
|
17
19
|
|
|
18
|
-
throw Error (`Validation problem with ${
|
|
20
|
+
throw Error (`Validation problem with ${this.formatPosition (parsedNode)}: ${cause.message}`, {cause})
|
|
19
21
|
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -47,13 +49,19 @@ class XMLValidationState {
|
|
|
47
49
|
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
formatPosition ({src}) {
|
|
53
|
+
|
|
54
|
+
const [line, char] = this.getPosition ()
|
|
55
|
+
|
|
56
|
+
return `${src} at line ${line}, position ${char}`
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
50
60
|
blameUnexpectedTag (parsedNode, match) {
|
|
51
61
|
|
|
52
62
|
const expected = match.allExpected (parsedNode); if (expected == null) this.blameNothingExpected ()
|
|
53
63
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
throw Error (`Unexpected ${src} at position ${BigInt (this.getPosition ()) - BigInt (length)}, expected: ${expected}`)
|
|
64
|
+
throw Error (`Unexpected ${this.formatPosition (parsedNode)}, expected: ${expected}`)
|
|
57
65
|
|
|
58
66
|
}
|
|
59
67
|
|
|
@@ -101,8 +109,8 @@ class XMLValidationState {
|
|
|
101
109
|
|
|
102
110
|
}
|
|
103
111
|
catch (cause) {
|
|
104
|
-
|
|
105
|
-
throw Error (`Validation problem with the contents of
|
|
112
|
+
|
|
113
|
+
throw Error (`Validation problem with the contents of ${this.formatPosition (this.parsedNode)}: ${cause.message}`, {cause})
|
|
106
114
|
|
|
107
115
|
}
|
|
108
116
|
|
|
@@ -118,6 +126,8 @@ class XMLValidationState {
|
|
|
118
126
|
|
|
119
127
|
if (isAnyAttributeAllowed) continue
|
|
120
128
|
|
|
129
|
+
if (attributesMap.getNamespaceURI (name) === XSINamespace) continue
|
|
130
|
+
|
|
121
131
|
throw Error (`Unknown attribute: "${name}"`)
|
|
122
132
|
|
|
123
133
|
}
|