@rgrove/parse-xml 4.1.0 → 4.2.0
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 +31 -31
- package/dist/browser.js +209 -236
- package/dist/browser.js.map +3 -3
- package/dist/global.min.js +8 -8
- package/dist/global.min.js.map +3 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/Parser.d.ts +4 -0
- package/dist/lib/Parser.d.ts.map +1 -1
- package/dist/lib/Parser.js +48 -39
- package/dist/lib/Parser.js.map +1 -1
- package/dist/lib/StringScanner.d.ts +10 -16
- package/dist/lib/StringScanner.d.ts.map +1 -1
- package/dist/lib/StringScanner.js +54 -77
- package/dist/lib/StringScanner.js.map +1 -1
- package/dist/lib/XmlDeclaration.js.map +1 -1
- package/dist/lib/XmlDocument.js.map +1 -1
- package/dist/lib/XmlDocumentType.js.map +1 -1
- package/dist/lib/XmlElement.js.map +1 -1
- package/dist/lib/XmlError.js.map +1 -1
- package/dist/lib/XmlNode.js.map +1 -1
- package/dist/lib/syntax.d.ts.map +1 -1
- package/dist/lib/syntax.js +17 -22
- package/dist/lib/syntax.js.map +1 -1
- package/package.json +14 -19
- package/src/lib/Parser.ts +52 -42
- package/src/lib/StringScanner.ts +56 -93
- package/src/lib/syntax.ts +11 -17
package/dist/browser.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @rgrove/parse-xml v4.
|
|
1
|
+
/*! @rgrove/parse-xml v4.2.0 | ISC License | Copyright Ryan Grove */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -40,24 +40,24 @@ var emptyString = "";
|
|
|
40
40
|
var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
41
41
|
var StringScanner = class {
|
|
42
42
|
constructor(string) {
|
|
43
|
-
this.k = this.
|
|
43
|
+
this.k = this.u(string, true);
|
|
44
44
|
this.d = 0;
|
|
45
45
|
this.length = string.length;
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
48
|
-
if (this.
|
|
46
|
+
this.l = this.k !== this.length;
|
|
47
|
+
this.h = string;
|
|
48
|
+
if (this.l) {
|
|
49
49
|
let charsToBytes = [];
|
|
50
50
|
for (let byteIndex = 0, charIndex = 0; charIndex < this.k; ++charIndex) {
|
|
51
51
|
charsToBytes[charIndex] = byteIndex;
|
|
52
52
|
byteIndex += string.codePointAt(byteIndex) > 65535 ? 2 : 1;
|
|
53
53
|
}
|
|
54
|
-
this.
|
|
54
|
+
this.A = charsToBytes;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Whether the current character index is at the end of the input string.
|
|
59
59
|
*/
|
|
60
|
-
get
|
|
60
|
+
get B() {
|
|
61
61
|
return this.d >= this.k;
|
|
62
62
|
}
|
|
63
63
|
// -- Protected Methods ------------------------------------------------------
|
|
@@ -65,7 +65,7 @@ var StringScanner = class {
|
|
|
65
65
|
* Returns the number of characters in the given string, which may differ from
|
|
66
66
|
* the byte length if the string contains multibyte characters.
|
|
67
67
|
*/
|
|
68
|
-
|
|
68
|
+
u(string, multiByteSafe = this.l) {
|
|
69
69
|
return multiByteSafe ? string.replace(surrogatePair, "_").length : string.length;
|
|
70
70
|
}
|
|
71
71
|
// -- Public Methods ---------------------------------------------------------
|
|
@@ -73,16 +73,16 @@ var StringScanner = class {
|
|
|
73
73
|
* Advances the scanner by the given number of characters, stopping if the end
|
|
74
74
|
* of the string is reached.
|
|
75
75
|
*/
|
|
76
|
-
|
|
76
|
+
p(count = 1) {
|
|
77
77
|
this.d = Math.min(this.k, this.d + count);
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
80
|
* Returns the byte index of the given character index in the string. The two
|
|
81
81
|
* may differ in strings that contain multibyte characters.
|
|
82
82
|
*/
|
|
83
|
-
|
|
83
|
+
f(charIndex = this.d) {
|
|
84
84
|
var _a;
|
|
85
|
-
return this.
|
|
85
|
+
return this.l ? (_a = this.A[charIndex]) != null ? _a : Infinity : charIndex;
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
88
|
* Consumes and returns the given number of characters if possible, advancing
|
|
@@ -90,46 +90,53 @@ var StringScanner = class {
|
|
|
90
90
|
*
|
|
91
91
|
* If no characters could be consumed, an empty string will be returned.
|
|
92
92
|
*/
|
|
93
|
-
|
|
94
|
-
let chars = this.
|
|
95
|
-
this.
|
|
93
|
+
G(charCount = 1) {
|
|
94
|
+
let chars = this.m(charCount);
|
|
95
|
+
this.p(charCount);
|
|
96
96
|
return chars;
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
|
-
* Consumes
|
|
100
|
-
*
|
|
99
|
+
* Consumes and returns the given number of bytes if possible, advancing the
|
|
100
|
+
* scanner and stopping if the end of the string is reached.
|
|
101
101
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
102
|
+
* It's up to the caller to ensure that the given byte count doesn't split a
|
|
103
|
+
* multibyte character.
|
|
104
104
|
*
|
|
105
|
-
*
|
|
105
|
+
* If no bytes could be consumed, an empty string will be returned.
|
|
106
106
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
let result = regex.exec(this.m);
|
|
113
|
-
if (result === null || result.length === 0) {
|
|
114
|
-
return emptyString;
|
|
115
|
-
}
|
|
116
|
-
let match = result[0];
|
|
117
|
-
this.g(this.q(match));
|
|
118
|
-
return match;
|
|
107
|
+
v(byteCount) {
|
|
108
|
+
let byteIndex = this.f();
|
|
109
|
+
let result = this.h.slice(byteIndex, byteIndex + byteCount);
|
|
110
|
+
this.p(this.u(result));
|
|
111
|
+
return result;
|
|
119
112
|
}
|
|
120
113
|
/**
|
|
121
|
-
* Consumes and returns all characters for which the given function returns
|
|
122
|
-
*
|
|
123
|
-
*
|
|
114
|
+
* Consumes and returns all characters for which the given function returns
|
|
115
|
+
* `true`, stopping when `false` is returned or the end of the input is
|
|
116
|
+
* reached.
|
|
124
117
|
*/
|
|
125
|
-
|
|
126
|
-
let
|
|
127
|
-
let
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
118
|
+
w(fn) {
|
|
119
|
+
let { length, l: multiByteMode, h: string } = this;
|
|
120
|
+
let startByteIndex = this.f();
|
|
121
|
+
let endByteIndex = startByteIndex;
|
|
122
|
+
if (multiByteMode) {
|
|
123
|
+
while (endByteIndex < length) {
|
|
124
|
+
let char = string[endByteIndex];
|
|
125
|
+
let isSurrogatePair = char >= "\uD800" && char <= "\uDBFF";
|
|
126
|
+
if (isSurrogatePair) {
|
|
127
|
+
char += string[endByteIndex + 1];
|
|
128
|
+
}
|
|
129
|
+
if (!fn(char)) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
endByteIndex += isSurrogatePair ? 2 : 1;
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
while (endByteIndex < length && fn(string[endByteIndex])) {
|
|
136
|
+
++endByteIndex;
|
|
137
|
+
}
|
|
131
138
|
}
|
|
132
|
-
return
|
|
139
|
+
return this.v(endByteIndex - startByteIndex);
|
|
133
140
|
}
|
|
134
141
|
/**
|
|
135
142
|
* Consumes the given string if it exists at the current character index, and
|
|
@@ -138,29 +145,11 @@ var StringScanner = class {
|
|
|
138
145
|
* If the given string doesn't exist at the current character index, an empty
|
|
139
146
|
* string will be returned and the scanner will not be advanced.
|
|
140
147
|
*/
|
|
141
|
-
Q(stringToConsume) {
|
|
142
|
-
if (this.b(stringToConsume)) {
|
|
143
|
-
return stringToConsume;
|
|
144
|
-
}
|
|
145
|
-
if (this.n) {
|
|
146
|
-
let { length } = stringToConsume;
|
|
147
|
-
let charLengthToMatch = this.q(stringToConsume);
|
|
148
|
-
if (charLengthToMatch !== length && stringToConsume === this.h(charLengthToMatch)) {
|
|
149
|
-
this.g(charLengthToMatch);
|
|
150
|
-
return stringToConsume;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return emptyString;
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Does the same thing as `consumeString()`, but doesn't support consuming
|
|
157
|
-
* multibyte characters. This can be faster if you only need to match single
|
|
158
|
-
* byte characters.
|
|
159
|
-
*/
|
|
160
148
|
b(stringToConsume) {
|
|
161
149
|
let { length } = stringToConsume;
|
|
162
|
-
|
|
163
|
-
|
|
150
|
+
let byteIndex = this.f();
|
|
151
|
+
if (stringToConsume === this.h.slice(byteIndex, byteIndex + length)) {
|
|
152
|
+
this.p(length === 1 ? 1 : this.u(stringToConsume));
|
|
164
153
|
return stringToConsume;
|
|
165
154
|
}
|
|
166
155
|
return emptyString;
|
|
@@ -172,15 +161,9 @@ var StringScanner = class {
|
|
|
172
161
|
*
|
|
173
162
|
* Returns the consumed string, or an empty string if nothing was consumed.
|
|
174
163
|
*/
|
|
175
|
-
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
if (matchByteIndex <= 0) {
|
|
179
|
-
return emptyString;
|
|
180
|
-
}
|
|
181
|
-
let result = restOfString.slice(0, matchByteIndex);
|
|
182
|
-
this.g(this.q(result));
|
|
183
|
-
return result;
|
|
164
|
+
x(regex) {
|
|
165
|
+
let matchByteIndex = this.h.slice(this.f()).search(regex);
|
|
166
|
+
return matchByteIndex > 0 ? this.v(matchByteIndex) : emptyString;
|
|
184
167
|
}
|
|
185
168
|
/**
|
|
186
169
|
* Consumes characters until the given string is found, advancing the scanner
|
|
@@ -189,34 +172,19 @@ var StringScanner = class {
|
|
|
189
172
|
*
|
|
190
173
|
* Returns the consumed string, or an empty string if nothing was consumed.
|
|
191
174
|
*/
|
|
192
|
-
|
|
193
|
-
let
|
|
194
|
-
let
|
|
195
|
-
|
|
196
|
-
if (matchByteIndex <= 0) {
|
|
197
|
-
return emptyString;
|
|
198
|
-
}
|
|
199
|
-
let result = string.slice(byteIndex, matchByteIndex);
|
|
200
|
-
this.g(this.q(result));
|
|
201
|
-
return result;
|
|
175
|
+
s(searchString) {
|
|
176
|
+
let byteIndex = this.f();
|
|
177
|
+
let matchByteIndex = this.h.indexOf(searchString, byteIndex);
|
|
178
|
+
return matchByteIndex > 0 ? this.v(matchByteIndex - byteIndex) : emptyString;
|
|
202
179
|
}
|
|
203
180
|
/**
|
|
204
181
|
* Returns the given number of characters starting at the current character
|
|
205
182
|
* index, without advancing the scanner and without exceeding the end of the
|
|
206
183
|
* input string.
|
|
207
184
|
*/
|
|
208
|
-
|
|
209
|
-
let { d: charIndex,
|
|
210
|
-
|
|
211
|
-
if (charIndex >= this.k) {
|
|
212
|
-
return emptyString;
|
|
213
|
-
}
|
|
214
|
-
return string.slice(
|
|
215
|
-
this.i(charIndex),
|
|
216
|
-
this.i(charIndex + count)
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
return string.slice(charIndex, charIndex + count);
|
|
185
|
+
m(count = 1) {
|
|
186
|
+
let { d: charIndex, h: string } = this;
|
|
187
|
+
return this.l ? string.slice(this.f(charIndex), this.f(charIndex + count)) : string.slice(charIndex, charIndex + count);
|
|
220
188
|
}
|
|
221
189
|
/**
|
|
222
190
|
* Resets the scanner position to the given character _index_, or to the start
|
|
@@ -225,14 +193,14 @@ var StringScanner = class {
|
|
|
225
193
|
* If _index_ is negative, the scanner position will be moved backward by that
|
|
226
194
|
* many characters, stopping if the beginning of the string is reached.
|
|
227
195
|
*/
|
|
228
|
-
|
|
196
|
+
n(index = 0) {
|
|
229
197
|
this.d = index >= 0 ? Math.min(this.k, index) : Math.max(0, this.d + index);
|
|
230
198
|
}
|
|
231
199
|
};
|
|
232
200
|
|
|
233
201
|
// src/lib/syntax.ts
|
|
234
|
-
var attValueCharDoubleQuote = /[
|
|
235
|
-
var attValueCharSingleQuote = /[
|
|
202
|
+
var attValueCharDoubleQuote = /["&<]/;
|
|
203
|
+
var attValueCharSingleQuote = /['&<]/;
|
|
236
204
|
var attValueNormalizedWhitespace = /\r\n|[\n\r\t]/g;
|
|
237
205
|
var endCharData = /<|&|]]>/;
|
|
238
206
|
var predefinedEntities = Object.freeze(Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
@@ -243,28 +211,25 @@ var predefinedEntities = Object.freeze(Object.assign(/* @__PURE__ */ Object.crea
|
|
|
243
211
|
quot: '"'
|
|
244
212
|
}));
|
|
245
213
|
function isNameChar(char) {
|
|
246
|
-
let cp =
|
|
247
|
-
return cp >= 97 && cp <= 122 || cp >= 65 && cp <= 90 || cp >= 48 && cp <= 57 || cp === 45 || cp === 46 || cp === 183 || cp >= 768 && cp <= 879 || cp
|
|
214
|
+
let cp = char.codePointAt(0);
|
|
215
|
+
return cp >= 97 && cp <= 122 || cp >= 65 && cp <= 90 || cp >= 48 && cp <= 57 || cp === 45 || cp === 46 || cp === 183 || cp >= 768 && cp <= 879 || cp === 8255 || cp === 8256 || isNameStartChar(char, cp);
|
|
248
216
|
}
|
|
249
|
-
function isNameStartChar(char, cp =
|
|
250
|
-
return cp >= 97 && cp <= 122 || cp >= 65 && cp <= 90 || cp === 58 || cp === 95 || cp >= 192 && cp <= 214 || cp >= 216 && cp <= 246 || cp >= 248 && cp <= 767 || cp >= 880 && cp <= 893 || cp >= 895 && cp <= 8191 || cp
|
|
217
|
+
function isNameStartChar(char, cp = char.codePointAt(0)) {
|
|
218
|
+
return cp >= 97 && cp <= 122 || cp >= 65 && cp <= 90 || cp === 58 || cp === 95 || cp >= 192 && cp <= 214 || cp >= 216 && cp <= 246 || cp >= 248 && cp <= 767 || cp >= 880 && cp <= 893 || cp >= 895 && cp <= 8191 || cp === 8204 || cp === 8205 || cp >= 8304 && cp <= 8591 || cp >= 11264 && cp <= 12271 || cp >= 12289 && cp <= 55295 || cp >= 63744 && cp <= 64975 || cp >= 65008 && cp <= 65533 || cp >= 65536 && cp <= 983039;
|
|
251
219
|
}
|
|
252
220
|
function isReferenceChar(char) {
|
|
253
221
|
return char === "#" || isNameChar(char);
|
|
254
222
|
}
|
|
255
223
|
function isWhitespace(char) {
|
|
256
|
-
let cp =
|
|
224
|
+
let cp = char.codePointAt(0);
|
|
257
225
|
return cp === 32 || cp === 9 || cp === 10 || cp === 13;
|
|
258
226
|
}
|
|
259
227
|
function isXmlCodePoint(cp) {
|
|
260
|
-
return cp
|
|
261
|
-
}
|
|
262
|
-
function getCodePoint(char) {
|
|
263
|
-
return char.codePointAt(0) || -1;
|
|
228
|
+
return cp >= 32 && cp <= 55295 || cp === 10 || cp === 9 || cp === 13 || cp >= 57344 && cp <= 65533 || cp >= 65536 && cp <= 1114111;
|
|
264
229
|
}
|
|
265
230
|
|
|
266
231
|
// src/lib/XmlNode.ts
|
|
267
|
-
var _XmlNode = class {
|
|
232
|
+
var _XmlNode = class _XmlNode {
|
|
268
233
|
constructor() {
|
|
269
234
|
/**
|
|
270
235
|
* Parent node of this node, or `null` if this node has no parent.
|
|
@@ -345,39 +310,39 @@ var _XmlNode = class {
|
|
|
345
310
|
return json;
|
|
346
311
|
}
|
|
347
312
|
};
|
|
348
|
-
var XmlNode = _XmlNode;
|
|
349
313
|
/**
|
|
350
314
|
* Type value for an `XmlCdata` node.
|
|
351
315
|
*/
|
|
352
|
-
|
|
316
|
+
_XmlNode.TYPE_CDATA = "cdata";
|
|
353
317
|
/**
|
|
354
318
|
* Type value for an `XmlComment` node.
|
|
355
319
|
*/
|
|
356
|
-
|
|
320
|
+
_XmlNode.TYPE_COMMENT = "comment";
|
|
357
321
|
/**
|
|
358
322
|
* Type value for an `XmlDocument` node.
|
|
359
323
|
*/
|
|
360
|
-
|
|
324
|
+
_XmlNode.TYPE_DOCUMENT = "document";
|
|
361
325
|
/**
|
|
362
326
|
* Type value for an `XmlDocumentType` node.
|
|
363
327
|
*/
|
|
364
|
-
|
|
328
|
+
_XmlNode.TYPE_DOCUMENT_TYPE = "doctype";
|
|
365
329
|
/**
|
|
366
330
|
* Type value for an `XmlElement` node.
|
|
367
331
|
*/
|
|
368
|
-
|
|
332
|
+
_XmlNode.TYPE_ELEMENT = "element";
|
|
369
333
|
/**
|
|
370
334
|
* Type value for an `XmlProcessingInstruction` node.
|
|
371
335
|
*/
|
|
372
|
-
|
|
336
|
+
_XmlNode.TYPE_PROCESSING_INSTRUCTION = "pi";
|
|
373
337
|
/**
|
|
374
338
|
* Type value for an `XmlText` node.
|
|
375
339
|
*/
|
|
376
|
-
|
|
340
|
+
_XmlNode.TYPE_TEXT = "text";
|
|
377
341
|
/**
|
|
378
342
|
* Type value for an `XmlDeclaration` node.
|
|
379
343
|
*/
|
|
380
|
-
|
|
344
|
+
_XmlNode.TYPE_XML_DECLARATION = "xmldecl";
|
|
345
|
+
var XmlNode = _XmlNode;
|
|
381
346
|
|
|
382
347
|
// src/lib/XmlText.ts
|
|
383
348
|
var XmlText = class extends XmlNode {
|
|
@@ -442,7 +407,7 @@ var XmlDeclaration = class extends XmlNode {
|
|
|
442
407
|
};
|
|
443
408
|
|
|
444
409
|
// src/lib/XmlElement.ts
|
|
445
|
-
var XmlElement = class extends XmlNode {
|
|
410
|
+
var XmlElement = class _XmlElement extends XmlNode {
|
|
446
411
|
constructor(name, attributes = /* @__PURE__ */ Object.create(null), children = []) {
|
|
447
412
|
super();
|
|
448
413
|
this.name = name;
|
|
@@ -457,7 +422,7 @@ var XmlElement = class extends XmlNode {
|
|
|
457
422
|
}
|
|
458
423
|
get preserveWhitespace() {
|
|
459
424
|
let node = this;
|
|
460
|
-
while (node instanceof
|
|
425
|
+
while (node instanceof _XmlElement) {
|
|
461
426
|
if ("xml:space" in node.attributes) {
|
|
462
427
|
return node.attributes["xml:space"] === "preserve";
|
|
463
428
|
}
|
|
@@ -611,42 +576,33 @@ var Parser = class {
|
|
|
611
576
|
*/
|
|
612
577
|
constructor(xml, options = {}) {
|
|
613
578
|
let doc = this.document = new XmlDocument();
|
|
614
|
-
|
|
615
|
-
this.
|
|
616
|
-
this.
|
|
617
|
-
if (this.
|
|
579
|
+
this.j = doc;
|
|
580
|
+
this.g = options;
|
|
581
|
+
this.c = new StringScanner(xml);
|
|
582
|
+
if (this.g.includeOffsets) {
|
|
618
583
|
doc.start = 0;
|
|
619
584
|
doc.end = xml.length;
|
|
620
585
|
}
|
|
621
|
-
|
|
622
|
-
this.H();
|
|
623
|
-
if (!this.B()) {
|
|
624
|
-
throw this.a("Root element is missing or invalid");
|
|
625
|
-
}
|
|
626
|
-
while (this.w()) {
|
|
627
|
-
}
|
|
628
|
-
if (!scanner.z) {
|
|
629
|
-
throw this.a("Extra content at the end of the document");
|
|
630
|
-
}
|
|
586
|
+
this.parse();
|
|
631
587
|
}
|
|
632
588
|
/**
|
|
633
589
|
* Adds the given `XmlNode` as a child of `this.currentNode`.
|
|
634
590
|
*/
|
|
635
|
-
|
|
636
|
-
node.parent = this.
|
|
637
|
-
if (this.
|
|
638
|
-
node.start = this.c.
|
|
639
|
-
node.end = this.c.
|
|
591
|
+
i(node, charIndex) {
|
|
592
|
+
node.parent = this.j;
|
|
593
|
+
if (this.g.includeOffsets) {
|
|
594
|
+
node.start = this.c.f(charIndex);
|
|
595
|
+
node.end = this.c.f();
|
|
640
596
|
}
|
|
641
|
-
this.
|
|
597
|
+
this.j.children.push(node);
|
|
642
598
|
return true;
|
|
643
599
|
}
|
|
644
600
|
/**
|
|
645
601
|
* Adds the given _text_ to the document, either by appending it to a
|
|
646
602
|
* preceding `XmlText` node (if possible) or by creating a new `XmlText` node.
|
|
647
603
|
*/
|
|
648
|
-
|
|
649
|
-
let { children } = this.
|
|
604
|
+
y(text, charIndex) {
|
|
605
|
+
let { children } = this.j;
|
|
650
606
|
let { length } = children;
|
|
651
607
|
text = normalizeLineBreaks(text);
|
|
652
608
|
if (length > 0) {
|
|
@@ -654,27 +610,27 @@ var Parser = class {
|
|
|
654
610
|
if ((prevNode == null ? void 0 : prevNode.type) === XmlNode.TYPE_TEXT) {
|
|
655
611
|
let textNode = prevNode;
|
|
656
612
|
textNode.text += text;
|
|
657
|
-
if (this.
|
|
658
|
-
textNode.end = this.c.
|
|
613
|
+
if (this.g.includeOffsets) {
|
|
614
|
+
textNode.end = this.c.f();
|
|
659
615
|
}
|
|
660
616
|
return true;
|
|
661
617
|
}
|
|
662
618
|
}
|
|
663
|
-
return this.
|
|
619
|
+
return this.i(new XmlText(text), charIndex);
|
|
664
620
|
}
|
|
665
621
|
/**
|
|
666
622
|
* Consumes element attributes.
|
|
667
623
|
*
|
|
668
624
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-starttags
|
|
669
625
|
*/
|
|
670
|
-
|
|
626
|
+
H() {
|
|
671
627
|
let attributes = /* @__PURE__ */ Object.create(null);
|
|
672
628
|
while (this.e()) {
|
|
673
|
-
let attrName = this.
|
|
629
|
+
let attrName = this.q();
|
|
674
630
|
if (!attrName) {
|
|
675
631
|
break;
|
|
676
632
|
}
|
|
677
|
-
let attrValue = this.
|
|
633
|
+
let attrValue = this.t() && this.I();
|
|
678
634
|
if (attrValue === false) {
|
|
679
635
|
throw this.a("Attribute value expected");
|
|
680
636
|
}
|
|
@@ -686,7 +642,7 @@ var Parser = class {
|
|
|
686
642
|
}
|
|
687
643
|
attributes[attrName] = attrValue;
|
|
688
644
|
}
|
|
689
|
-
if (this.
|
|
645
|
+
if (this.g.sortAttributes) {
|
|
690
646
|
let attrNames = Object.keys(attributes).sort();
|
|
691
647
|
let sortedAttributes = /* @__PURE__ */ Object.create(null);
|
|
692
648
|
for (let i = 0; i < attrNames.length; ++i) {
|
|
@@ -707,41 +663,40 @@ var Parser = class {
|
|
|
707
663
|
*
|
|
708
664
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
|
709
665
|
*/
|
|
710
|
-
|
|
666
|
+
I() {
|
|
711
667
|
let { c: scanner } = this;
|
|
712
|
-
let quote = scanner.
|
|
668
|
+
let quote = scanner.m();
|
|
713
669
|
if (quote !== '"' && quote !== "'") {
|
|
714
670
|
return false;
|
|
715
671
|
}
|
|
716
|
-
scanner.
|
|
672
|
+
scanner.p();
|
|
717
673
|
let chars;
|
|
718
674
|
let isClosed = false;
|
|
719
675
|
let value = emptyString2;
|
|
720
676
|
let regex = quote === '"' ? attValueCharDoubleQuote : attValueCharSingleQuote;
|
|
721
|
-
matchLoop:
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
break matchLoop;
|
|
739
|
-
}
|
|
677
|
+
matchLoop: while (!scanner.B) {
|
|
678
|
+
chars = scanner.x(regex);
|
|
679
|
+
if (chars) {
|
|
680
|
+
this.o(chars);
|
|
681
|
+
value += chars.replace(attValueNormalizedWhitespace, " ");
|
|
682
|
+
}
|
|
683
|
+
switch (scanner.m()) {
|
|
684
|
+
case quote:
|
|
685
|
+
isClosed = true;
|
|
686
|
+
break matchLoop;
|
|
687
|
+
case "&":
|
|
688
|
+
value += this.C();
|
|
689
|
+
continue;
|
|
690
|
+
case "<":
|
|
691
|
+
throw this.a("Unescaped `<` is not allowed in an attribute value");
|
|
692
|
+
default:
|
|
693
|
+
break matchLoop;
|
|
740
694
|
}
|
|
695
|
+
}
|
|
741
696
|
if (!isClosed) {
|
|
742
697
|
throw this.a("Unclosed attribute");
|
|
743
698
|
}
|
|
744
|
-
scanner.
|
|
699
|
+
scanner.p();
|
|
745
700
|
return value;
|
|
746
701
|
}
|
|
747
702
|
/**
|
|
@@ -750,18 +705,18 @@ var Parser = class {
|
|
|
750
705
|
* @returns Whether a CDATA section was consumed.
|
|
751
706
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-cdata-sect
|
|
752
707
|
*/
|
|
753
|
-
|
|
708
|
+
J() {
|
|
754
709
|
let { c: scanner } = this;
|
|
755
710
|
let startIndex = scanner.d;
|
|
756
711
|
if (!scanner.b("<![CDATA[")) {
|
|
757
712
|
return false;
|
|
758
713
|
}
|
|
759
|
-
let text = scanner.
|
|
760
|
-
this.
|
|
714
|
+
let text = scanner.s("]]>");
|
|
715
|
+
this.o(text);
|
|
761
716
|
if (!scanner.b("]]>")) {
|
|
762
717
|
throw this.a("Unclosed CDATA section");
|
|
763
718
|
}
|
|
764
|
-
return this.
|
|
719
|
+
return this.g.preserveCdata ? this.i(new XmlCdata(normalizeLineBreaks(text)), startIndex) : this.y(text, startIndex);
|
|
765
720
|
}
|
|
766
721
|
/**
|
|
767
722
|
* Consumes character data if possible.
|
|
@@ -769,18 +724,18 @@ var Parser = class {
|
|
|
769
724
|
* @returns Whether character data was consumed.
|
|
770
725
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
|
|
771
726
|
*/
|
|
772
|
-
|
|
727
|
+
K() {
|
|
773
728
|
let { c: scanner } = this;
|
|
774
729
|
let startIndex = scanner.d;
|
|
775
|
-
let charData = scanner.
|
|
730
|
+
let charData = scanner.x(endCharData);
|
|
776
731
|
if (!charData) {
|
|
777
732
|
return false;
|
|
778
733
|
}
|
|
779
|
-
this.
|
|
780
|
-
if (scanner.
|
|
734
|
+
this.o(charData);
|
|
735
|
+
if (scanner.m(3) === "]]>") {
|
|
781
736
|
throw this.a("Element content may not contain the CDATA section close delimiter `]]>`");
|
|
782
737
|
}
|
|
783
|
-
return this.
|
|
738
|
+
return this.y(charData, startIndex);
|
|
784
739
|
}
|
|
785
740
|
/**
|
|
786
741
|
* Consumes a comment if possible.
|
|
@@ -794,15 +749,15 @@ var Parser = class {
|
|
|
794
749
|
if (!scanner.b("<!--")) {
|
|
795
750
|
return false;
|
|
796
751
|
}
|
|
797
|
-
let content = scanner.
|
|
798
|
-
this.
|
|
752
|
+
let content = scanner.s("--");
|
|
753
|
+
this.o(content);
|
|
799
754
|
if (!scanner.b("-->")) {
|
|
800
|
-
if (scanner.
|
|
755
|
+
if (scanner.m(2) === "--") {
|
|
801
756
|
throw this.a("The string `--` isn't allowed inside a comment");
|
|
802
757
|
}
|
|
803
758
|
throw this.a("Unclosed comment");
|
|
804
759
|
}
|
|
805
|
-
return this.
|
|
760
|
+
return this.g.preserveComments ? this.i(new XmlComment(normalizeLineBreaks(content)), startIndex) : true;
|
|
806
761
|
}
|
|
807
762
|
/**
|
|
808
763
|
* Consumes a reference in a content context if possible.
|
|
@@ -813,10 +768,10 @@ var Parser = class {
|
|
|
813
768
|
* @returns Whether a reference was consumed.
|
|
814
769
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#entproc
|
|
815
770
|
*/
|
|
816
|
-
|
|
771
|
+
L() {
|
|
817
772
|
let startIndex = this.c.d;
|
|
818
773
|
let ref = this.C();
|
|
819
|
-
return ref ? this.
|
|
774
|
+
return ref ? this.y(ref, startIndex) : false;
|
|
820
775
|
}
|
|
821
776
|
/**
|
|
822
777
|
* Consumes a doctype declaration if possible.
|
|
@@ -827,13 +782,13 @@ var Parser = class {
|
|
|
827
782
|
* @returns Whether a doctype declaration was consumed.
|
|
828
783
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dtd
|
|
829
784
|
*/
|
|
830
|
-
|
|
785
|
+
M() {
|
|
831
786
|
let { c: scanner } = this;
|
|
832
787
|
let startIndex = scanner.d;
|
|
833
788
|
if (!scanner.b("<!DOCTYPE")) {
|
|
834
789
|
return false;
|
|
835
790
|
}
|
|
836
|
-
let name = this.e() && this.
|
|
791
|
+
let name = this.e() && this.q();
|
|
837
792
|
if (!name) {
|
|
838
793
|
throw this.a("Expected a name");
|
|
839
794
|
}
|
|
@@ -841,7 +796,7 @@ var Parser = class {
|
|
|
841
796
|
let systemId;
|
|
842
797
|
if (this.e()) {
|
|
843
798
|
if (scanner.b("PUBLIC")) {
|
|
844
|
-
publicId = this.e() && this.
|
|
799
|
+
publicId = this.e() && this.N();
|
|
845
800
|
if (publicId === false) {
|
|
846
801
|
throw this.a("Expected a public identifier");
|
|
847
802
|
}
|
|
@@ -849,7 +804,7 @@ var Parser = class {
|
|
|
849
804
|
}
|
|
850
805
|
if (publicId !== void 0 || scanner.b("SYSTEM")) {
|
|
851
806
|
this.e();
|
|
852
|
-
systemId = this.
|
|
807
|
+
systemId = this.r();
|
|
853
808
|
if (systemId === false) {
|
|
854
809
|
throw this.a("Expected a system identifier");
|
|
855
810
|
}
|
|
@@ -858,7 +813,7 @@ var Parser = class {
|
|
|
858
813
|
}
|
|
859
814
|
let internalSubset;
|
|
860
815
|
if (scanner.b("[")) {
|
|
861
|
-
internalSubset = scanner.
|
|
816
|
+
internalSubset = scanner.x(/\][\x20\t\r\n]*>/);
|
|
862
817
|
if (!scanner.b("]")) {
|
|
863
818
|
throw this.a("Unclosed internal subset");
|
|
864
819
|
}
|
|
@@ -867,7 +822,7 @@ var Parser = class {
|
|
|
867
822
|
if (!scanner.b(">")) {
|
|
868
823
|
throw this.a("Unclosed doctype declaration");
|
|
869
824
|
}
|
|
870
|
-
return this.
|
|
825
|
+
return this.g.preserveDocumentType ? this.i(new XmlDocumentType(name, publicId, systemId, internalSubset), startIndex) : true;
|
|
871
826
|
}
|
|
872
827
|
/**
|
|
873
828
|
* Consumes an element if possible.
|
|
@@ -875,42 +830,42 @@ var Parser = class {
|
|
|
875
830
|
* @returns Whether an element was consumed.
|
|
876
831
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-element
|
|
877
832
|
*/
|
|
878
|
-
|
|
833
|
+
E() {
|
|
879
834
|
let { c: scanner } = this;
|
|
880
835
|
let startIndex = scanner.d;
|
|
881
836
|
if (!scanner.b("<")) {
|
|
882
837
|
return false;
|
|
883
838
|
}
|
|
884
|
-
let name = this.
|
|
839
|
+
let name = this.q();
|
|
885
840
|
if (!name) {
|
|
886
|
-
scanner.
|
|
841
|
+
scanner.n(startIndex);
|
|
887
842
|
return false;
|
|
888
843
|
}
|
|
889
|
-
let attributes = this.
|
|
844
|
+
let attributes = this.H();
|
|
890
845
|
let isEmpty = !!scanner.b("/>");
|
|
891
846
|
let element = new XmlElement(name, attributes);
|
|
892
|
-
element.parent = this.
|
|
847
|
+
element.parent = this.j;
|
|
893
848
|
if (!isEmpty) {
|
|
894
849
|
if (!scanner.b(">")) {
|
|
895
850
|
throw this.a(`Unclosed start tag for element \`${name}\``);
|
|
896
851
|
}
|
|
897
|
-
this.
|
|
852
|
+
this.j = element;
|
|
898
853
|
do {
|
|
899
|
-
this.
|
|
900
|
-
} while (this.
|
|
854
|
+
this.K();
|
|
855
|
+
} while (this.E() || this.L() || this.J() || this.F() || this.D());
|
|
901
856
|
let endTagMark = scanner.d;
|
|
902
857
|
let endTagName;
|
|
903
|
-
if (!scanner.b("</") || !(endTagName = this.
|
|
904
|
-
scanner.
|
|
858
|
+
if (!scanner.b("</") || !(endTagName = this.q()) || endTagName !== name) {
|
|
859
|
+
scanner.n(endTagMark);
|
|
905
860
|
throw this.a(`Missing end tag for element ${name}`);
|
|
906
861
|
}
|
|
907
862
|
this.e();
|
|
908
863
|
if (!scanner.b(">")) {
|
|
909
864
|
throw this.a(`Unclosed end tag for element ${name}`);
|
|
910
865
|
}
|
|
911
|
-
this.
|
|
866
|
+
this.j = element.parent;
|
|
912
867
|
}
|
|
913
|
-
return this.
|
|
868
|
+
return this.i(element, startIndex);
|
|
914
869
|
}
|
|
915
870
|
/**
|
|
916
871
|
* Consumes an `Eq` production if possible.
|
|
@@ -918,7 +873,7 @@ var Parser = class {
|
|
|
918
873
|
* @returns Whether an `Eq` production was consumed.
|
|
919
874
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Eq
|
|
920
875
|
*/
|
|
921
|
-
|
|
876
|
+
t() {
|
|
922
877
|
this.e();
|
|
923
878
|
if (this.c.b("=")) {
|
|
924
879
|
this.e();
|
|
@@ -932,8 +887,8 @@ var Parser = class {
|
|
|
932
887
|
* @returns Whether anything was consumed.
|
|
933
888
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Misc
|
|
934
889
|
*/
|
|
935
|
-
|
|
936
|
-
return this.D() || this.
|
|
890
|
+
z() {
|
|
891
|
+
return this.D() || this.F() || this.e();
|
|
937
892
|
}
|
|
938
893
|
/**
|
|
939
894
|
* Consumes one or more `Name` characters if possible.
|
|
@@ -941,8 +896,8 @@ var Parser = class {
|
|
|
941
896
|
* @returns `Name` characters, or an empty string if none were consumed.
|
|
942
897
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Name
|
|
943
898
|
*/
|
|
944
|
-
|
|
945
|
-
return isNameStartChar(this.c.
|
|
899
|
+
q() {
|
|
900
|
+
return isNameStartChar(this.c.m()) ? this.c.w(isNameChar) : emptyString2;
|
|
946
901
|
}
|
|
947
902
|
/**
|
|
948
903
|
* Consumes a processing instruction if possible.
|
|
@@ -950,16 +905,16 @@ var Parser = class {
|
|
|
950
905
|
* @returns Whether a processing instruction was consumed.
|
|
951
906
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-pi
|
|
952
907
|
*/
|
|
953
|
-
|
|
908
|
+
F() {
|
|
954
909
|
let { c: scanner } = this;
|
|
955
910
|
let startIndex = scanner.d;
|
|
956
911
|
if (!scanner.b("<?")) {
|
|
957
912
|
return false;
|
|
958
913
|
}
|
|
959
|
-
let name = this.
|
|
914
|
+
let name = this.q();
|
|
960
915
|
if (name) {
|
|
961
916
|
if (name.toLowerCase() === "xml") {
|
|
962
|
-
scanner.
|
|
917
|
+
scanner.n(startIndex);
|
|
963
918
|
throw this.a("XML declaration isn't allowed here");
|
|
964
919
|
}
|
|
965
920
|
} else {
|
|
@@ -967,16 +922,16 @@ var Parser = class {
|
|
|
967
922
|
}
|
|
968
923
|
if (!this.e()) {
|
|
969
924
|
if (scanner.b("?>")) {
|
|
970
|
-
return this.
|
|
925
|
+
return this.i(new XmlProcessingInstruction(name), startIndex);
|
|
971
926
|
}
|
|
972
927
|
throw this.a("Whitespace is required after a processing instruction name");
|
|
973
928
|
}
|
|
974
|
-
let content = scanner.
|
|
975
|
-
this.
|
|
929
|
+
let content = scanner.s("?>");
|
|
930
|
+
this.o(content);
|
|
976
931
|
if (!scanner.b("?>")) {
|
|
977
932
|
throw this.a("Unterminated processing instruction");
|
|
978
933
|
}
|
|
979
|
-
return this.
|
|
934
|
+
return this.i(new XmlProcessingInstruction(name, normalizeLineBreaks(content)), startIndex);
|
|
980
935
|
}
|
|
981
936
|
/**
|
|
982
937
|
* Consumes a prolog if possible.
|
|
@@ -984,14 +939,14 @@ var Parser = class {
|
|
|
984
939
|
* @returns Whether a prolog was consumed.
|
|
985
940
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-prolog-dtd
|
|
986
941
|
*/
|
|
987
|
-
|
|
942
|
+
O() {
|
|
988
943
|
let { c: scanner } = this;
|
|
989
944
|
let startIndex = scanner.d;
|
|
990
945
|
this.P();
|
|
991
|
-
while (this.
|
|
946
|
+
while (this.z()) {
|
|
992
947
|
}
|
|
993
|
-
if (this.
|
|
994
|
-
while (this.
|
|
948
|
+
if (this.M()) {
|
|
949
|
+
while (this.z()) {
|
|
995
950
|
}
|
|
996
951
|
}
|
|
997
952
|
return startIndex < scanner.d;
|
|
@@ -1006,11 +961,11 @@ var Parser = class {
|
|
|
1006
961
|
*
|
|
1007
962
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-PubidLiteral
|
|
1008
963
|
*/
|
|
1009
|
-
|
|
964
|
+
N() {
|
|
1010
965
|
let startIndex = this.c.d;
|
|
1011
|
-
let value = this.
|
|
966
|
+
let value = this.r();
|
|
1012
967
|
if (value !== false && !/^[-\x20\r\na-zA-Z0-9'()+,./:=?;!*#@$_%]*$/.test(value)) {
|
|
1013
|
-
this.c.
|
|
968
|
+
this.c.n(startIndex);
|
|
1014
969
|
throw this.a("Invalid character in public identifier");
|
|
1015
970
|
}
|
|
1016
971
|
return value;
|
|
@@ -1032,8 +987,8 @@ var Parser = class {
|
|
|
1032
987
|
if (!scanner.b("&")) {
|
|
1033
988
|
return false;
|
|
1034
989
|
}
|
|
1035
|
-
let ref = scanner.
|
|
1036
|
-
if (scanner.
|
|
990
|
+
let ref = scanner.w(isReferenceChar);
|
|
991
|
+
if (scanner.G() !== ";") {
|
|
1037
992
|
throw this.a("Unterminated reference (a reference must end with `;`)");
|
|
1038
993
|
}
|
|
1039
994
|
let parsedValue;
|
|
@@ -1052,7 +1007,7 @@ var Parser = class {
|
|
|
1052
1007
|
let {
|
|
1053
1008
|
ignoreUndefinedEntities,
|
|
1054
1009
|
resolveUndefinedEntity
|
|
1055
|
-
} = this.
|
|
1010
|
+
} = this.g;
|
|
1056
1011
|
let wrappedRef = `&${ref};`;
|
|
1057
1012
|
if (resolveUndefinedEntity) {
|
|
1058
1013
|
let resolvedValue = resolveUndefinedEntity(wrappedRef);
|
|
@@ -1067,7 +1022,7 @@ var Parser = class {
|
|
|
1067
1022
|
if (ignoreUndefinedEntities) {
|
|
1068
1023
|
return wrappedRef;
|
|
1069
1024
|
}
|
|
1070
|
-
scanner.
|
|
1025
|
+
scanner.n(-wrappedRef.length);
|
|
1071
1026
|
throw this.a(`Named entity isn't defined: ${wrappedRef}`);
|
|
1072
1027
|
}
|
|
1073
1028
|
}
|
|
@@ -1086,14 +1041,14 @@ var Parser = class {
|
|
|
1086
1041
|
*
|
|
1087
1042
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-SystemLiteral
|
|
1088
1043
|
*/
|
|
1089
|
-
|
|
1044
|
+
r() {
|
|
1090
1045
|
let { c: scanner } = this;
|
|
1091
1046
|
let quote = scanner.b('"') || scanner.b("'");
|
|
1092
1047
|
if (!quote) {
|
|
1093
1048
|
return false;
|
|
1094
1049
|
}
|
|
1095
|
-
let value = scanner.
|
|
1096
|
-
this.
|
|
1050
|
+
let value = scanner.s(quote);
|
|
1051
|
+
this.o(value);
|
|
1097
1052
|
if (!scanner.b(quote)) {
|
|
1098
1053
|
throw this.a("Missing end quote");
|
|
1099
1054
|
}
|
|
@@ -1106,7 +1061,7 @@ var Parser = class {
|
|
|
1106
1061
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
|
|
1107
1062
|
*/
|
|
1108
1063
|
e() {
|
|
1109
|
-
return !!this.c.
|
|
1064
|
+
return !!this.c.w(isWhitespace);
|
|
1110
1065
|
}
|
|
1111
1066
|
/**
|
|
1112
1067
|
* Consumes an XML declaration if possible.
|
|
@@ -1123,7 +1078,7 @@ var Parser = class {
|
|
|
1123
1078
|
if (!this.e()) {
|
|
1124
1079
|
throw this.a("Invalid XML declaration");
|
|
1125
1080
|
}
|
|
1126
|
-
let version = !!scanner.b("version") && this.
|
|
1081
|
+
let version = !!scanner.b("version") && this.t() && this.r();
|
|
1127
1082
|
if (version === false) {
|
|
1128
1083
|
throw this.a("XML version is missing or invalid");
|
|
1129
1084
|
} else if (!/^1\.[0-9]+$/.test(version)) {
|
|
@@ -1132,11 +1087,14 @@ var Parser = class {
|
|
|
1132
1087
|
let encoding;
|
|
1133
1088
|
let standalone;
|
|
1134
1089
|
if (this.e()) {
|
|
1135
|
-
encoding = !!scanner.b("encoding") && this.
|
|
1090
|
+
encoding = !!scanner.b("encoding") && this.t() && this.r();
|
|
1136
1091
|
if (encoding) {
|
|
1092
|
+
if (!/^[A-Za-z][\w.-]*$/.test(encoding)) {
|
|
1093
|
+
throw this.a("Invalid character in encoding name");
|
|
1094
|
+
}
|
|
1137
1095
|
this.e();
|
|
1138
1096
|
}
|
|
1139
|
-
standalone = !!scanner.b("standalone") && this.
|
|
1097
|
+
standalone = !!scanner.b("standalone") && this.t() && this.r();
|
|
1140
1098
|
if (standalone) {
|
|
1141
1099
|
if (standalone !== "yes" && standalone !== "no") {
|
|
1142
1100
|
throw this.a('Only "yes" and "no" are permitted as values of `standalone`');
|
|
@@ -1147,7 +1105,7 @@ var Parser = class {
|
|
|
1147
1105
|
if (!scanner.b("?>")) {
|
|
1148
1106
|
throw this.a("Invalid or unclosed XML declaration");
|
|
1149
1107
|
}
|
|
1150
|
-
return this.
|
|
1108
|
+
return this.g.preserveXmlDeclaration ? this.i(new XmlDeclaration(
|
|
1151
1109
|
version,
|
|
1152
1110
|
encoding || void 0,
|
|
1153
1111
|
standalone || void 0
|
|
@@ -1158,18 +1116,33 @@ var Parser = class {
|
|
|
1158
1116
|
*/
|
|
1159
1117
|
a(message) {
|
|
1160
1118
|
let { c: scanner } = this;
|
|
1161
|
-
return new XmlError(message, scanner.d, scanner.
|
|
1119
|
+
return new XmlError(message, scanner.d, scanner.h);
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Parses the XML input.
|
|
1123
|
+
*/
|
|
1124
|
+
parse() {
|
|
1125
|
+
this.c.b("\uFEFF");
|
|
1126
|
+
this.O();
|
|
1127
|
+
if (!this.E()) {
|
|
1128
|
+
throw this.a("Root element is missing or invalid");
|
|
1129
|
+
}
|
|
1130
|
+
while (this.z()) {
|
|
1131
|
+
}
|
|
1132
|
+
if (!this.c.B) {
|
|
1133
|
+
throw this.a("Extra content at the end of the document");
|
|
1134
|
+
}
|
|
1162
1135
|
}
|
|
1163
1136
|
/**
|
|
1164
1137
|
* Throws an invalid character error if any character in the given _string_
|
|
1165
1138
|
* isn't a valid XML character.
|
|
1166
1139
|
*/
|
|
1167
|
-
|
|
1140
|
+
o(string) {
|
|
1168
1141
|
let { length } = string;
|
|
1169
1142
|
for (let i = 0; i < length; ++i) {
|
|
1170
1143
|
let cp = string.codePointAt(i);
|
|
1171
1144
|
if (!isXmlCodePoint(cp)) {
|
|
1172
|
-
this.c.
|
|
1145
|
+
this.c.n(-([...string].length - i));
|
|
1173
1146
|
throw this.a("Invalid character");
|
|
1174
1147
|
}
|
|
1175
1148
|
if (cp > 65535) {
|