xml-toolkit 1.1.5 → 1.1.6
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/README.md +5 -1
- package/lib/XMLMessages.js +34 -3
- package/lib/XMLParser.js +12 -6
- package/lib/XMLReader.js +11 -4
- package/lib/XMLSchema.js +2 -1
- package/lib/XMLSchemata.js +1 -1
- package/lib/simple/DT7.js +38 -47
- package/lib/simple/XSSimpleTypeDT.js +26 -4
- package/lib/validation/XMLValidationState.js +15 -32
- package/lib/validation/XMLValidatior.js +10 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,6 +30,8 @@ const parser = new XMLParser ({
|
|
|
30
30
|
|
|
31
31
|
const document = parser.process (xml)
|
|
32
32
|
|
|
33
|
+
// console.log (parser.validationMessages)
|
|
34
|
+
|
|
33
35
|
for (const element of document.detach ().children) {
|
|
34
36
|
console.log (element.attributes)
|
|
35
37
|
}
|
|
@@ -46,7 +48,9 @@ const records = new XMLReader ({
|
|
|
46
48
|
//xs,
|
|
47
49
|
filterElements : 'Record',
|
|
48
50
|
map : XMLNode.toObject ({})
|
|
49
|
-
})
|
|
51
|
+
})
|
|
52
|
+
//.on ('validation-message', s => console.log (s))
|
|
53
|
+
.process (xmlSource)
|
|
50
54
|
|
|
51
55
|
// ...then:
|
|
52
56
|
// await someLoader.load (records)
|
package/lib/XMLMessages.js
CHANGED
|
@@ -6,6 +6,9 @@ const VOCABULARY = new Map ([
|
|
|
6
6
|
['XML-00002', 'Unbalanced end element'],
|
|
7
7
|
['XML-00003', 'Unmatched end element, </${%s}> expected'],
|
|
8
8
|
|
|
9
|
+
['XSD-00001', 'Unknown namespace: %s'],
|
|
10
|
+
['XSD-00002', 'The element %s is not found in %s'],
|
|
11
|
+
|
|
9
12
|
['XVC-00001', 'No nested elements allowed inside %s'],
|
|
10
13
|
['XVC-00002', 'is unexpected here; should be %s'],
|
|
11
14
|
['XVC-00003', 'Unknown attribute: %s'],
|
|
@@ -28,7 +31,7 @@ const VOCABULARY = new Map ([
|
|
|
28
31
|
['XVS-00014', `'%s' is not a valid decimal: '%s' can occur only at the beginning`],
|
|
29
32
|
['XVS-00015', `'%s' is not a valid decimal: 2nd period occured at position %i`],
|
|
30
33
|
['XVS-00016', `'%s' is not a valid decimal: '%s' occured at position %i`],
|
|
31
|
-
['XVS-00017', `'%s' is not a valid decimal:
|
|
34
|
+
['XVS-00017', `'%s' is not a valid decimal: it has no digits at all`],
|
|
32
35
|
['XVS-00018', `'%s' has %i digits, only %i allowed`],
|
|
33
36
|
['XVS-00019', `'%s' has %i digits after period, only %i allowed`],
|
|
34
37
|
['XVS-00020', `No floating point number can be empty`],
|
|
@@ -37,6 +40,22 @@ const VOCABULARY = new Map ([
|
|
|
37
40
|
['XVS-00023', `For a dateTime value, the time part is mandatory, missing from '%s'`],
|
|
38
41
|
['XVS-00024', `For a dateTimeStamp value, both time and timezone parts are mandatory, missing from '%s'`],
|
|
39
42
|
['XVS-00025', `The year separator is not found in '%s'`],
|
|
43
|
+
['XVS-00026', `'%s': '%s' is not a valid year, must be 4 chars long`],
|
|
44
|
+
['XVS-00027', `'%s': The character at %i must be '-', not '%s'`],
|
|
45
|
+
['XVS-00028', `'%s': The day part must be 2 chars long, found '%s'`],
|
|
46
|
+
['XVS-00029', `'%s': Invalid time part: the character at position %i must be ':', not '%s'`],
|
|
47
|
+
['XVS-00030', `'%s': '%s' is not a valid year: '%s' at position %i`],
|
|
48
|
+
['XVS-00031', `'%s': Invalid month '%s'`],
|
|
49
|
+
['XVS-00032', `'%s': Invalid day '%s'`],
|
|
50
|
+
['XVS-00033', `'%s': Non existing day`],
|
|
51
|
+
['XVS-00034', `'%s': Invalid hour '%s'`],
|
|
52
|
+
['XVS-00035', `'%s': Invalid minute '%s'`],
|
|
53
|
+
['XVS-00036', `'%s': Invalid second '%s'`],
|
|
54
|
+
['XVS-00037', `'%s': Invalid TZ hour '%s'`],
|
|
55
|
+
['XVS-00038', `'%s': Invalid TZ minute '%s'`],
|
|
56
|
+
['XVS-00039', `'%s': Unless 'Z', the timezone must start with either '+' or '-', not '%s'`],
|
|
57
|
+
['XVS-00040', `'%s': Invalid timezone length '%i'`],
|
|
58
|
+
['XVS-00041', `'%s': Invalid timezone: ':' not found at position 3`],
|
|
40
59
|
|
|
41
60
|
])
|
|
42
61
|
|
|
@@ -46,9 +65,21 @@ class XMLMessages {
|
|
|
46
65
|
|
|
47
66
|
static format (args) {
|
|
48
67
|
|
|
49
|
-
|
|
68
|
+
const code = args [0]
|
|
69
|
+
|
|
70
|
+
args [0] = VOCABULARY.get (code)
|
|
71
|
+
|
|
72
|
+
return code + ' ' + util.format.apply (util, args)
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static raise (args) {
|
|
77
|
+
|
|
78
|
+
const error = Error (XMLMessages.format (args))
|
|
79
|
+
|
|
80
|
+
error.args = args
|
|
50
81
|
|
|
51
|
-
|
|
82
|
+
throw error
|
|
52
83
|
|
|
53
84
|
}
|
|
54
85
|
|
package/lib/XMLParser.js
CHANGED
|
@@ -48,6 +48,7 @@ const XMLParser = class {
|
|
|
48
48
|
this.text = ''
|
|
49
49
|
this.document = null
|
|
50
50
|
this.element = null
|
|
51
|
+
this.validationMessages = []
|
|
51
52
|
|
|
52
53
|
const {entityResolver} = this, nodes = new XMLIterator (src, {entityResolver})
|
|
53
54
|
|
|
@@ -67,9 +68,7 @@ const XMLParser = class {
|
|
|
67
68
|
|
|
68
69
|
if (this.stripSpace) this.text = this.text.trim ()
|
|
69
70
|
if (this.text.length === 0) break
|
|
70
|
-
if (this.validator) {
|
|
71
|
-
this.validator.characters (this.text)
|
|
72
|
-
}
|
|
71
|
+
if (this.validator) {this.validator.characters (this.text)}
|
|
73
72
|
(new XMLNode (this.text, null, SAXEvent.TYPES.CHARACTERS)).parent = this.element
|
|
74
73
|
this.text = ''
|
|
75
74
|
|
|
@@ -84,10 +83,17 @@ const XMLParser = class {
|
|
|
84
83
|
this.element = node
|
|
85
84
|
if (this.document === null) {
|
|
86
85
|
this.document = node
|
|
87
|
-
if (this.xs !== null)
|
|
86
|
+
if (this.xs !== null) {
|
|
87
|
+
try {
|
|
88
|
+
this.validator = new XMLValidatior (this.xs, node, nodes.position, message => this.validationMessages.push (message))
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
this.validationMessages.push (nodes.position + err.message)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
88
94
|
}
|
|
89
95
|
else {
|
|
90
|
-
if (this.
|
|
96
|
+
if (this.validator) this.validator.startElement (node)
|
|
91
97
|
}
|
|
92
98
|
break
|
|
93
99
|
|
|
@@ -98,7 +104,7 @@ const XMLParser = class {
|
|
|
98
104
|
node ['_ns_map'] = this.element ['_ns_map']
|
|
99
105
|
this.element.type = type
|
|
100
106
|
this.element = this.element.parent
|
|
101
|
-
if (this.
|
|
107
|
+
if (this.validator) this.validator.endElement (node)
|
|
102
108
|
break
|
|
103
109
|
|
|
104
110
|
}
|
package/lib/XMLReader.js
CHANGED
|
@@ -147,13 +147,20 @@ const XMLReader = class extends Transform {
|
|
|
147
147
|
if (!this.validator) switch (xmlNode.type) {
|
|
148
148
|
|
|
149
149
|
case SAXEvent.TYPES.START_ELEMENT:
|
|
150
|
-
|
|
150
|
+
try {
|
|
151
|
+
this.validator = new XMLValidatior (this.xs, xmlNode, this.lex.position, s => this.emit ('validation-message', s))
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
this.emit ('validation-message', this.lex.position + err.message)
|
|
155
|
+
}
|
|
151
156
|
|
|
152
157
|
default:
|
|
153
158
|
return
|
|
154
159
|
|
|
155
160
|
}
|
|
156
161
|
|
|
162
|
+
// if (!this.validator) return
|
|
163
|
+
|
|
157
164
|
switch (xmlNode.type) {
|
|
158
165
|
|
|
159
166
|
case SAXEvent.TYPES.START_ELEMENT : return this.validator.startElement (xmlNode)
|
|
@@ -170,17 +177,17 @@ const XMLReader = class extends Transform {
|
|
|
170
177
|
|
|
171
178
|
if (type !== null) xmlNode.type = type
|
|
172
179
|
|
|
173
|
-
if (this.xs) try {
|
|
180
|
+
if (this.xs) /*try {*/
|
|
174
181
|
|
|
175
182
|
this.validate (xmlNode)
|
|
176
|
-
|
|
183
|
+
/*
|
|
177
184
|
}
|
|
178
185
|
catch (error) {
|
|
179
186
|
|
|
180
187
|
this.destroy (error)
|
|
181
188
|
|
|
182
189
|
}
|
|
183
|
-
|
|
190
|
+
*/
|
|
184
191
|
const {filter} = this; if (filter !== null) {
|
|
185
192
|
|
|
186
193
|
if (!filter (xmlNode)) return
|
package/lib/XMLSchema.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const XMLMessages = require ('./XMLMessages.js')
|
|
1
2
|
const TYPES = Symbol ('_types')
|
|
2
3
|
|
|
3
4
|
const FORM_U = 'unqualified'
|
|
@@ -91,7 +92,7 @@ const XMLSchema = class extends Map {
|
|
|
91
92
|
|
|
92
93
|
const el = this.get (localName)
|
|
93
94
|
|
|
94
|
-
if (!el || el.localName !== 'element')
|
|
95
|
+
if (!el || el.localName !== 'element') XMLMessages.raise (['XSD-00002', localName, this.targetNamespace])
|
|
95
96
|
|
|
96
97
|
return el
|
|
97
98
|
|
package/lib/XMLSchemata.js
CHANGED
|
@@ -168,7 +168,7 @@ const XMLSchemata = class extends Map {
|
|
|
168
168
|
|
|
169
169
|
getSchema (namespaceURI) {
|
|
170
170
|
|
|
171
|
-
if (!this.has (namespaceURI))
|
|
171
|
+
if (!this.has (namespaceURI)) XMLMessages.raise (['XSD-00001', namespaceURI])
|
|
172
172
|
|
|
173
173
|
return this.get (namespaceURI)
|
|
174
174
|
|
package/lib/simple/DT7.js
CHANGED
|
@@ -9,44 +9,44 @@ const CH_9 = '9'.charCodeAt (0)
|
|
|
9
9
|
|
|
10
10
|
const tzCache = new Set (['Z', '+14:00', '-14:00'])
|
|
11
11
|
|
|
12
|
-
const die = payload => {
|
|
13
|
-
|
|
14
|
-
const err = Error ('DT7 error')
|
|
15
|
-
|
|
16
|
-
err.payload = payload
|
|
17
|
-
|
|
18
|
-
throw err
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
12
|
class DT7 {
|
|
23
13
|
|
|
24
14
|
constructor (src) {
|
|
25
15
|
|
|
26
16
|
const t = typeof src; if (t !== 'string') throw Error (`The Seven-property Date Time Model can only be constructed from a string, not a(n) ${t}`)
|
|
27
17
|
|
|
28
|
-
const {length} = src; if (length < MIN_LENGTH) die (['XVS-00005', src, length, MIN_LENGTH])
|
|
29
|
-
|
|
30
18
|
this.src = src
|
|
31
19
|
|
|
20
|
+
const {length} = src; if (length < MIN_LENGTH) this.raise ('XVS-00005', length, MIN_LENGTH)
|
|
21
|
+
|
|
32
22
|
this.parse ()
|
|
33
23
|
this.validate ()
|
|
34
24
|
|
|
35
25
|
}
|
|
36
26
|
|
|
27
|
+
raise (code, ...args) {
|
|
28
|
+
|
|
29
|
+
const err = Error ('DT7 error')
|
|
30
|
+
|
|
31
|
+
err.payload = [code, this.src, ...args]
|
|
32
|
+
|
|
33
|
+
throw err
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
37
|
parse () {
|
|
38
38
|
|
|
39
39
|
this.posMonth = this.src.indexOf ('-', 1)
|
|
40
40
|
|
|
41
|
-
if (this.posMonth === -1)
|
|
42
|
-
|
|
43
|
-
if (this.posMonth < 3) throw Error (`'${this.year}' is not a valid year: cannot be shorter than 4 characters`)
|
|
41
|
+
if (this.posMonth === -1) this.raise ('XVS-00025')
|
|
44
42
|
|
|
45
|
-
if (this.
|
|
43
|
+
if (this.posMonth < 3) this.raise ('XVS-00026', this.year)
|
|
44
|
+
|
|
45
|
+
if (this.src.charCodeAt (this.posDay) !== CH_MINUS) this.raise ('XVS-00027', this.posDay, this.src.charAt (this.posDay))
|
|
46
46
|
|
|
47
47
|
const {length} = this.src
|
|
48
48
|
|
|
49
|
-
if (length < this.endOfDate)
|
|
49
|
+
if (length < this.endOfDate) this.raise ('XVS-00028', this.day)
|
|
50
50
|
|
|
51
51
|
if (length !== (this.endOfDateTime = this.endOfDate)) this.parseAfterDate ()
|
|
52
52
|
|
|
@@ -56,12 +56,8 @@ class DT7 {
|
|
|
56
56
|
|
|
57
57
|
if (this.src.charCodeAt (this.endOfDate) !== CH_T) return
|
|
58
58
|
|
|
59
|
-
for (const pos of [this.endOfHour, this.endOfMinute])
|
|
60
|
-
|
|
61
|
-
if (this.src.charCodeAt (pos) !== CH_COLON)
|
|
59
|
+
for (const pos of [this.endOfHour, this.endOfMinute]) if (this.src.charCodeAt (pos) !== CH_COLON) this.raise ('XVS-00029', pos, this.src.charAt (pos))
|
|
62
60
|
|
|
63
|
-
throw Error (`Invalid time part: the character at position ${pos} must be ':', not '${this.src.charAt (pos)}'`)
|
|
64
|
-
|
|
65
61
|
this.hasTime = true
|
|
66
62
|
|
|
67
63
|
this.parseAfterMinute ()
|
|
@@ -174,13 +170,13 @@ class DT7 {
|
|
|
174
170
|
|
|
175
171
|
const {year} = this, {length} = year, base = year.charCodeAt (0) === CH_MINUS ? 1 : 0
|
|
176
172
|
|
|
177
|
-
if (year.charCodeAt (base) === CH_0 && length - base !== 4)
|
|
173
|
+
if (year.charCodeAt (base) === CH_0 && length - base !== 4) this.raise ('XVS-00026', year)
|
|
178
174
|
|
|
179
175
|
for (let i = base; i < length; i ++) {
|
|
180
176
|
|
|
181
177
|
const c = year.charCodeAt (i)
|
|
182
178
|
|
|
183
|
-
if (c > CH_9 || c < CH_0)
|
|
179
|
+
if (c > CH_9 || c < CH_0) this.raise ('XVS-00030', year, year.charAt (i), i)
|
|
184
180
|
|
|
185
181
|
}
|
|
186
182
|
|
|
@@ -190,7 +186,13 @@ class DT7 {
|
|
|
190
186
|
|
|
191
187
|
const {month} = this
|
|
192
188
|
|
|
193
|
-
if (month < '01' || month > '12')
|
|
189
|
+
if (month < '01' || month > '12') this.raise ('XVS-00031', month)
|
|
190
|
+
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
validate2digits (value, code, max = '59', min = '00') {
|
|
194
|
+
|
|
195
|
+
if (value < min || value > max) this.raise (code, value)
|
|
194
196
|
|
|
195
197
|
}
|
|
196
198
|
|
|
@@ -198,11 +200,11 @@ class DT7 {
|
|
|
198
200
|
|
|
199
201
|
const {day} = this
|
|
200
202
|
|
|
201
|
-
|
|
203
|
+
this.validate2digits (day, 'XVS-00032', '31', '01')
|
|
202
204
|
|
|
203
205
|
if (day === '31' || (this.month === '02' && day > '28')) {
|
|
204
206
|
|
|
205
|
-
if (new Date (this.src.substring (0, this.endOfDate)).getDate () != day)
|
|
207
|
+
if (new Date (this.src.substring (0, this.endOfDate)).getDate () != day) this.raise ('XVS-00033')
|
|
206
208
|
|
|
207
209
|
}
|
|
208
210
|
|
|
@@ -210,14 +212,12 @@ class DT7 {
|
|
|
210
212
|
|
|
211
213
|
validateTime () {
|
|
212
214
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (hour < '00' || hour > '23') throw Error (`Invalid hour`)
|
|
216
|
-
if (minute < '00' || minute > '59') throw Error (`Invalid minute`)
|
|
215
|
+
this.validate2digits (this.hour, 'XVS-00034', '23')
|
|
216
|
+
this.validate2digits (this.minute, 'XVS-00035')
|
|
217
217
|
|
|
218
|
-
const intSecond = second.length === 2 ? second : second.substring (0, 2)
|
|
218
|
+
const {second} = this, intSecond = second.length === 2 ? second : second.substring (0, 2)
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
this.validate2digits (intSecond, 'XVS-00036')
|
|
221
221
|
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -230,24 +230,15 @@ class DT7 {
|
|
|
230
230
|
case CH_MINUS:
|
|
231
231
|
break
|
|
232
232
|
default:
|
|
233
|
-
|
|
233
|
+
this.raise ('XVS-00039', tz.charAt (0))
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
if (tz.length !== 6)
|
|
236
|
+
if (tz.length !== 6) this.raise ('XVS-00040', tz.length)
|
|
237
237
|
|
|
238
|
-
if (tz.charCodeAt (3) !== CH_COLON)
|
|
238
|
+
if (tz.charCodeAt (3) !== CH_COLON) this.raise ('XVS-00041')
|
|
239
239
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const hh = tz.substring (1, 3); if (hh < '00' || hh > '13') throw Error (`Invalid TZ hour: ${hh}`)
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
{
|
|
247
|
-
|
|
248
|
-
const mm = tz.substring (4, 6); if (mm < '00' || mm > '59') throw Error (`Invalid TZ minute: ${mm}`)
|
|
249
|
-
|
|
250
|
-
}
|
|
240
|
+
this.validate2digits (tz.substring (1, 3), 'XVS-00037', '13')
|
|
241
|
+
this.validate2digits (tz.substring (4, 6), 'XVS-00038')
|
|
251
242
|
|
|
252
243
|
tzCache.add (tz)
|
|
253
244
|
|
|
@@ -64,9 +64,20 @@ class XSSimpleTypeDateTime extends XSSimpleTypeDT {
|
|
|
64
64
|
|
|
65
65
|
testFormat (s) {
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
try {
|
|
68
|
+
|
|
69
|
+
const dt7 = new DT7 (s)
|
|
70
|
+
|
|
71
|
+
if (dt7.hour === undefined) return ['XVS-00023', s]
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
|
|
76
|
+
if ('payload' in err) return err.payload
|
|
68
77
|
|
|
69
|
-
|
|
78
|
+
throw err
|
|
79
|
+
|
|
80
|
+
}
|
|
70
81
|
|
|
71
82
|
}
|
|
72
83
|
|
|
@@ -86,9 +97,20 @@ class XSSimpleTypeDateTimeStamp extends XSSimpleTypeDateTime {
|
|
|
86
97
|
|
|
87
98
|
testFormat (s) {
|
|
88
99
|
|
|
89
|
-
|
|
100
|
+
try {
|
|
101
|
+
|
|
102
|
+
const dt7 = new DT7 (s)
|
|
103
|
+
|
|
104
|
+
if (dt7.hour === undefined || dt7.tz === undefined) return ['XVS-00024', s]
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
|
|
109
|
+
if ('payload' in err) return err.payload
|
|
90
110
|
|
|
91
|
-
|
|
111
|
+
throw err
|
|
112
|
+
|
|
113
|
+
}
|
|
92
114
|
|
|
93
115
|
}
|
|
94
116
|
|
|
@@ -8,53 +8,36 @@ class XMLValidationState {
|
|
|
8
8
|
|
|
9
9
|
constructor (parent, parsedNode, elementDefinition) {
|
|
10
10
|
|
|
11
|
-
this.xs = (this.parent = parent).xs
|
|
11
|
+
const xs = this.xs = (this.parent = parent).xs
|
|
12
12
|
this.parsedNode = parsedNode
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
const typeDefinition = xs.getTypeDefinition (elementDefinition)
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
catch (cause) {
|
|
16
|
+
this.anyType = xs.getAnyType (typeDefinition)
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
this.validateAttributes (this.parsedNode.attributes)
|
|
22
19
|
|
|
23
|
-
}
|
|
20
|
+
const {content} = this.anyType; if (content) this.match = content.createMatch ()
|
|
24
21
|
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
warn (message, cause) {
|
|
28
25
|
|
|
29
|
-
this.parent.warn (message, cause)
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
setTypeFrom (element) {
|
|
34
|
-
|
|
35
|
-
const {xs} = this
|
|
36
|
-
|
|
37
|
-
const typeDefinition = xs.getTypeDefinition (element)
|
|
38
|
-
|
|
39
|
-
this.anyType = xs.getAnyType (typeDefinition)
|
|
40
|
-
|
|
41
|
-
this.validateAttributes (this.parsedNode.attributes)
|
|
42
|
-
|
|
43
|
-
const {content} = this.anyType; if (content) this.match = content.createMatch ()
|
|
26
|
+
return this.parent.warn (message, cause)
|
|
44
27
|
|
|
45
28
|
}
|
|
46
29
|
|
|
47
30
|
blameNothingExpected () {
|
|
48
31
|
|
|
49
|
-
this.warn (['XVC-00001', this.parsedNode.src])
|
|
32
|
+
return this.warn (['XVC-00001', this.parsedNode.src])
|
|
50
33
|
|
|
51
34
|
}
|
|
52
35
|
|
|
53
36
|
blameUnexpectedTag (parsedNode, match) {
|
|
54
37
|
|
|
55
|
-
const expected = match.allExpected (parsedNode); if (expected == null) this.blameNothingExpected ()
|
|
38
|
+
const expected = match.allExpected (parsedNode); if (expected == null) return this.blameNothingExpected ()
|
|
56
39
|
|
|
57
|
-
this.warn (['XVC-00002', expected])
|
|
40
|
+
return this.warn (['XVC-00002', expected])
|
|
58
41
|
|
|
59
42
|
}
|
|
60
43
|
|
|
@@ -62,9 +45,9 @@ class XMLValidationState {
|
|
|
62
45
|
|
|
63
46
|
if (this.#child !== null) return this.#child.startElement (parsedNode)
|
|
64
47
|
|
|
65
|
-
const {match} = this; if (!match) this.warn (['XVC-00001', this.anyType.debugQName])
|
|
48
|
+
const {match} = this; if (!match) return this.warn (['XVC-00001', this.anyType.debugQName])
|
|
66
49
|
|
|
67
|
-
const element = match.getElementDefinition (parsedNode); if (!element) this.blameUnexpectedTag (parsedNode, match)
|
|
50
|
+
const element = match.getElementDefinition (parsedNode); if (!element) return this.blameUnexpectedTag (parsedNode, match)
|
|
68
51
|
|
|
69
52
|
if (element.localName === 'any') return
|
|
70
53
|
|
|
@@ -78,7 +61,7 @@ class XMLValidationState {
|
|
|
78
61
|
|
|
79
62
|
if (!this.#hadText) this.characters ('')
|
|
80
63
|
|
|
81
|
-
const {match} = this; if (match && !match.isSatisfied) this.blameUnexpectedTag (parsedNode, match)
|
|
64
|
+
const {match} = this; if (match && !match.isSatisfied) return this.blameUnexpectedTag (parsedNode, match)
|
|
82
65
|
|
|
83
66
|
return null
|
|
84
67
|
|
|
@@ -146,7 +129,7 @@ class XMLValidationState {
|
|
|
146
129
|
|
|
147
130
|
if (attributesMap.getNamespaceURI (name) === XSINamespace) continue
|
|
148
131
|
|
|
149
|
-
this.warn (['XVC-00003', name])
|
|
132
|
+
return this.warn (['XVC-00003', name])
|
|
150
133
|
|
|
151
134
|
}
|
|
152
135
|
|
|
@@ -154,7 +137,7 @@ class XMLValidationState {
|
|
|
154
137
|
|
|
155
138
|
const {attributes: {fixed, type}} = def
|
|
156
139
|
|
|
157
|
-
if (typeof fixed === 'string' && value !== fixed) this.warn (['XVC-00004', name, fixed, value])
|
|
140
|
+
if (typeof fixed === 'string' && value !== fixed) return this.warn (['XVC-00004', name, fixed, value])
|
|
158
141
|
|
|
159
142
|
if (type) {
|
|
160
143
|
|
|
@@ -173,7 +156,7 @@ class XMLValidationState {
|
|
|
173
156
|
|
|
174
157
|
for (const [name, def] of attributes) if (!matched.has (def)) {
|
|
175
158
|
|
|
176
|
-
if (def.attributes.use === 'required') this.warn (['XVC-00005', name])
|
|
159
|
+
if (def.attributes.use === 'required') return this.warn (['XVC-00005', name])
|
|
177
160
|
|
|
178
161
|
if ('default' in def.attributes) attributesMap.set (name, def.attributes.default)
|
|
179
162
|
|
|
@@ -4,12 +4,13 @@ class XMLValidatior {
|
|
|
4
4
|
|
|
5
5
|
#state = null
|
|
6
6
|
|
|
7
|
-
constructor (xs, rootNode, position) {
|
|
7
|
+
constructor (xs, rootNode, position, onMessage) {
|
|
8
8
|
|
|
9
9
|
this.xs = xs
|
|
10
10
|
this.position = position
|
|
11
11
|
|
|
12
|
-
this.
|
|
12
|
+
this.onMessage = onMessage
|
|
13
|
+
this.startElement (rootNode)
|
|
13
14
|
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -17,7 +18,13 @@ class XMLValidatior {
|
|
|
17
18
|
|
|
18
19
|
const {position} = this
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
if (Array.isArray (message)) message = position.format (message)
|
|
22
|
+
|
|
23
|
+
this.onMessage (message)
|
|
24
|
+
|
|
25
|
+
return null
|
|
26
|
+
|
|
27
|
+
// throw Error (message)
|
|
21
28
|
|
|
22
29
|
}
|
|
23
30
|
|