read-excel-file 9.2.0 → 9.3.1
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/.gitlab-ci.yml +1 -1
- package/CHANGELOG.md +5 -0
- package/README.md +153 -50
- package/bundle/read-excel-file.min.js +1 -1
- package/bundle/read-excel-file.min.js.map +1 -1
- package/bundle/read-excel-file.min.old.js +2 -0
- package/bundle/read-excel-file.min.old.js.map +1 -0
- package/commonjs/export/convertValuesFromUint8ArraysToStrings.js +3 -0
- package/commonjs/export/convertValuesFromUint8ArraysToStrings.js.map +1 -1
- package/commonjs/export/parseSheet.js +12 -9
- package/commonjs/export/parseSheet.js.map +1 -1
- package/commonjs/export/readSheetBrowser.js +6 -2
- package/commonjs/export/readSheetBrowser.js.map +1 -1
- package/commonjs/export/readSheetNode.js +6 -2
- package/commonjs/export/readSheetNode.js.map +1 -1
- package/commonjs/export/readSheetUniversal.js +14 -2
- package/commonjs/export/readSheetUniversal.js.map +1 -1
- package/commonjs/export/readSheetWebWorker.js +12 -2
- package/commonjs/export/readSheetWebWorker.js.map +1 -1
- package/commonjs/export/readXlsxFileBrowser.js +6 -2
- package/commonjs/export/readXlsxFileBrowser.js.map +1 -1
- package/commonjs/export/readXlsxFileNode.js +6 -2
- package/commonjs/export/readXlsxFileNode.js.map +1 -1
- package/commonjs/export/readXlsxFileUniversal.js +14 -2
- package/commonjs/export/readXlsxFileUniversal.js.map +1 -1
- package/commonjs/export/readXlsxFileWebWorker.js +12 -2
- package/commonjs/export/readXlsxFileWebWorker.js.map +1 -1
- package/commonjs/export/unpackXlsxFileBrowser.js +29 -6
- package/commonjs/export/unpackXlsxFileBrowser.js.map +1 -1
- package/commonjs/export/unpackXlsxFileNode.js +6 -0
- package/commonjs/export/unpackXlsxFileNode.js.map +1 -1
- package/commonjs/export/unpackXlsxFileUniversal.js +6 -0
- package/commonjs/export/unpackXlsxFileUniversal.js.map +1 -1
- package/commonjs/export/unpackXlsxFileWebWorker.js +14 -0
- package/commonjs/export/unpackXlsxFileWebWorker.js.map +1 -0
- package/commonjs/parseSheetData/parseSheetData.js +6 -6
- package/commonjs/parseSheetData/parseSheetData.js.map +1 -1
- package/commonjs/utility/checkpoint.js +33 -0
- package/commonjs/utility/checkpoint.js.map +1 -0
- package/commonjs/utility/isObject.js +15 -0
- package/commonjs/utility/isObject.js.map +1 -0
- package/commonjs/utility/isPromise.js +18 -0
- package/commonjs/utility/isPromise.js.map +1 -0
- package/commonjs/xlsx/convertCellsToData2dArray.js +0 -3
- package/commonjs/xlsx/convertCellsToData2dArray.js.map +1 -1
- package/commonjs/xlsx/isDateFormatStyle.js +2 -2
- package/commonjs/xlsx/isDateFormatStyle.js.map +1 -1
- package/commonjs/xlsx/parseCell.js +89 -24
- package/commonjs/xlsx/parseCell.js.map +1 -1
- package/{modules/xlsx/parseCellCoordinates.js → commonjs/xlsx/parseCellAddress.js} +18 -7
- package/commonjs/xlsx/parseCellAddress.js.map +1 -0
- package/commonjs/xlsx/parseCellValue.js +7 -23
- package/commonjs/xlsx/parseCellValue.js.map +1 -1
- package/commonjs/xlsx/parseFilePaths.js +31 -32
- package/commonjs/xlsx/parseFilePaths.js.map +1 -1
- package/commonjs/xlsx/parseNumber.js +20 -0
- package/commonjs/xlsx/parseNumber.js.map +1 -0
- package/commonjs/xlsx/parseSharedString.js +64 -0
- package/commonjs/xlsx/parseSharedString.js.map +1 -0
- package/commonjs/xlsx/parseSharedStrings.js +45 -5
- package/commonjs/xlsx/parseSharedStrings.js.map +1 -1
- package/commonjs/xlsx/parseSheet.js +93 -9
- package/commonjs/xlsx/parseSheet.js.map +1 -1
- package/commonjs/xlsx/parseSheetData.js +68 -0
- package/commonjs/xlsx/parseSheetData.js.map +1 -0
- package/commonjs/xlsx/parseSpreadsheetContents.js +244 -43
- package/commonjs/xlsx/parseSpreadsheetContents.js.map +1 -1
- package/commonjs/xlsx/parseSpreadsheetInfo.js +67 -36
- package/commonjs/xlsx/parseSpreadsheetInfo.js.map +1 -1
- package/commonjs/xlsx/parseStyles.js +89 -36
- package/commonjs/xlsx/parseStyles.js.map +1 -1
- package/commonjs/xml/dom.js +2 -1
- package/commonjs/xml/dom.js.map +1 -1
- package/commonjs/xml/parseXmlStream.js +14 -0
- package/commonjs/xml/parseXmlStream.js.map +1 -0
- package/commonjs/xml/parseXmlStream.sax.js +109 -0
- package/commonjs/xml/parseXmlStream.sax.js.map +1 -0
- package/commonjs/xml/parseXmlStream.saxen.code.js +953 -0
- package/commonjs/xml/parseXmlStream.saxen.code.js.map +1 -0
- package/commonjs/xml/parseXmlStream.saxen.js +85 -0
- package/commonjs/xml/parseXmlStream.saxen.js.map +1 -0
- package/commonjs/xml/xlsx.js +75 -40
- package/commonjs/xml/xlsx.js.map +1 -1
- package/commonjs/zip/unzipFromArrayBuffer.js +5 -14
- package/commonjs/zip/unzipFromArrayBuffer.js.map +1 -1
- package/commonjs/zip/unzipFromStream.fflate.js +154 -25
- package/commonjs/zip/unzipFromStream.fflate.js.map +1 -1
- package/commonjs/zip/unzipFromStream.js.map +1 -1
- package/commonjs/zip/unzipFromStream.unzipper.js +37 -26
- package/commonjs/zip/unzipFromStream.unzipper.js.map +1 -1
- package/modules/export/convertValuesFromUint8ArraysToStrings.js +2 -0
- package/modules/export/convertValuesFromUint8ArraysToStrings.js.map +1 -1
- package/modules/export/parseSheet.js +12 -9
- package/modules/export/parseSheet.js.map +1 -1
- package/modules/export/readSheetBrowser.js +5 -2
- package/modules/export/readSheetBrowser.js.map +1 -1
- package/modules/export/readSheetNode.js +5 -2
- package/modules/export/readSheetNode.js.map +1 -1
- package/modules/export/readSheetUniversal.js +14 -2
- package/modules/export/readSheetUniversal.js.map +1 -1
- package/modules/export/readSheetWebWorker.js +12 -2
- package/modules/export/readSheetWebWorker.js.map +1 -1
- package/modules/export/readXlsxFileBrowser.js +5 -2
- package/modules/export/readXlsxFileBrowser.js.map +1 -1
- package/modules/export/readXlsxFileNode.js +5 -2
- package/modules/export/readXlsxFileNode.js.map +1 -1
- package/modules/export/readXlsxFileUniversal.js +14 -2
- package/modules/export/readXlsxFileUniversal.js.map +1 -1
- package/modules/export/readXlsxFileWebWorker.js +12 -2
- package/modules/export/readXlsxFileWebWorker.js.map +1 -1
- package/modules/export/unpackXlsxFileBrowser.js +26 -6
- package/modules/export/unpackXlsxFileBrowser.js.map +1 -1
- package/modules/export/unpackXlsxFileNode.js +3 -0
- package/modules/export/unpackXlsxFileNode.js.map +1 -1
- package/modules/export/unpackXlsxFileUniversal.js +3 -0
- package/modules/export/unpackXlsxFileUniversal.js.map +1 -1
- package/modules/export/unpackXlsxFileWebWorker.js +6 -0
- package/modules/export/unpackXlsxFileWebWorker.js.map +1 -0
- package/modules/parseSheetData/parseSheetData.js +4 -4
- package/modules/parseSheetData/parseSheetData.js.map +1 -1
- package/modules/utility/checkpoint.js +25 -0
- package/modules/utility/checkpoint.js.map +1 -0
- package/modules/utility/isObject.js +9 -0
- package/modules/utility/isObject.js.map +1 -0
- package/modules/utility/isPromise.js +12 -0
- package/modules/utility/isPromise.js.map +1 -0
- package/modules/xlsx/convertCellsToData2dArray.js +0 -3
- package/modules/xlsx/convertCellsToData2dArray.js.map +1 -1
- package/modules/xlsx/isDateFormatStyle.js +2 -2
- package/modules/xlsx/isDateFormatStyle.js.map +1 -1
- package/modules/xlsx/parseCell.js +85 -24
- package/modules/xlsx/parseCell.js.map +1 -1
- package/{commonjs/xlsx/parseCellCoordinates.js → modules/xlsx/parseCellAddress.js} +12 -13
- package/modules/xlsx/parseCellAddress.js.map +1 -0
- package/modules/xlsx/parseCellValue.js +7 -23
- package/modules/xlsx/parseCellValue.js.map +1 -1
- package/modules/xlsx/parseFilePaths.js +31 -33
- package/modules/xlsx/parseFilePaths.js.map +1 -1
- package/modules/xlsx/parseNumber.js +14 -0
- package/modules/xlsx/parseNumber.js.map +1 -0
- package/modules/xlsx/parseSharedString.js +55 -0
- package/modules/xlsx/parseSharedString.js.map +1 -0
- package/modules/xlsx/parseSharedStrings.js +46 -5
- package/modules/xlsx/parseSharedStrings.js.map +1 -1
- package/modules/xlsx/parseSheet.js +91 -9
- package/modules/xlsx/parseSheet.js.map +1 -1
- package/modules/xlsx/parseSheetData.js +55 -0
- package/modules/xlsx/parseSheetData.js.map +1 -0
- package/modules/xlsx/parseSpreadsheetContents.js +242 -43
- package/modules/xlsx/parseSpreadsheetContents.js.map +1 -1
- package/modules/xlsx/parseSpreadsheetInfo.js +67 -37
- package/modules/xlsx/parseSpreadsheetInfo.js.map +1 -1
- package/modules/xlsx/parseStyles.js +88 -36
- package/modules/xlsx/parseStyles.js.map +1 -1
- package/modules/xml/dom.js +2 -1
- package/modules/xml/dom.js.map +1 -1
- package/modules/xml/parseXmlStream.js +18 -0
- package/modules/xml/parseXmlStream.js.map +1 -0
- package/modules/xml/parseXmlStream.sax.js +103 -0
- package/modules/xml/parseXmlStream.sax.js.map +1 -0
- package/modules/xml/parseXmlStream.saxen.code.js +947 -0
- package/modules/xml/parseXmlStream.saxen.code.js.map +1 -0
- package/modules/xml/parseXmlStream.saxen.js +79 -0
- package/modules/xml/parseXmlStream.saxen.js.map +1 -0
- package/modules/xml/xlsx.js +72 -36
- package/modules/xml/xlsx.js.map +1 -1
- package/modules/zip/unzipFromArrayBuffer.js +5 -14
- package/modules/zip/unzipFromArrayBuffer.js.map +1 -1
- package/modules/zip/unzipFromStream.fflate.js +157 -24
- package/modules/zip/unzipFromStream.fflate.js.map +1 -1
- package/modules/zip/unzipFromStream.js +56 -2
- package/modules/zip/unzipFromStream.js.map +1 -1
- package/modules/zip/unzipFromStream.unzipper.js +38 -26
- package/modules/zip/unzipFromStream.unzipper.js.map +1 -1
- package/package.json +4 -6
- package/commonjs/xlsx/parseCellCoordinates.js.map +0 -1
- package/commonjs/xlsx/parseCells.js +0 -34
- package/commonjs/xlsx/parseCells.js.map +0 -1
- package/commonjs/xlsx/parseSheetDimensions.js +0 -43
- package/commonjs/xlsx/parseSheetDimensions.js.map +0 -1
- package/commonjs/xml/xml.js +0 -13
- package/commonjs/xml/xml.js.map +0 -1
- package/commonjs/xml/xmlBrowser.js +0 -17
- package/commonjs/xml/xmlBrowser.js.map +0 -1
- package/commonjs/xml/xpath/xlsx-xpath.js +0 -92
- package/commonjs/xml/xpath/xlsx-xpath.js.map +0 -1
- package/commonjs/xml/xpath/xpathBrowser.js +0 -33
- package/commonjs/xml/xpath/xpathBrowser.js.map +0 -1
- package/commonjs/xml/xpath/xpathNode.js +0 -16
- package/commonjs/xml/xpath/xpathNode.js.map +0 -1
- package/modules/xlsx/parseCellCoordinates.js.map +0 -1
- package/modules/xlsx/parseCells.js +0 -27
- package/modules/xlsx/parseCells.js.map +0 -1
- package/modules/xlsx/parseSheetDimensions.js +0 -37
- package/modules/xlsx/parseSheetDimensions.js.map +0 -1
- package/modules/xml/xml.js +0 -7
- package/modules/xml/xml.js.map +0 -1
- package/modules/xml/xmlBrowser.js +0 -11
- package/modules/xml/xmlBrowser.js.map +0 -1
- package/modules/xml/xpath/xlsx-xpath.js +0 -73
- package/modules/xml/xpath/xlsx-xpath.js.map +0 -1
- package/modules/xml/xpath/xpathBrowser.js +0 -27
- package/modules/xml/xpath/xpathBrowser.js.map +0 -1
- package/modules/xml/xpath/xpathNode.js +0 -9
- package/modules/xml/xpath/xpathNode.js.map +0 -1
|
@@ -0,0 +1,947 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
// Here it uses a copy-paste of `saxen` source code instead of importing the `saxen` package itself.
|
|
3
|
+
// The reason is that `worker-f` package is used to run this XML parser in a separate thread,
|
|
4
|
+
// and doing that requires the entire code to reside in a single "self-contained" function.
|
|
5
|
+
// import { Parser } from 'saxen'
|
|
6
|
+
|
|
7
|
+
// This code was copy-pasted from `saxen` repository on Jun 23rd, 2026.
|
|
8
|
+
// The reason is that `worker-f` package is used to run `saxen` XML parser in a separate thread,
|
|
9
|
+
// and doing that requires the entire `saxen` code to reside in a single "self-contained" function.
|
|
10
|
+
|
|
11
|
+
export function Parser(options) {
|
|
12
|
+
// Copy-pasted from file: decode.js
|
|
13
|
+
|
|
14
|
+
var fromCharCode = String.fromCharCode;
|
|
15
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
16
|
+
var ENTITY_PATTERN = /&#(\d+);|&#x([0-9a-f]+);|&(\w+);/ig;
|
|
17
|
+
var ENTITY_MAPPING = {
|
|
18
|
+
'amp': '&',
|
|
19
|
+
'apos': '\'',
|
|
20
|
+
'gt': '>',
|
|
21
|
+
'lt': '<',
|
|
22
|
+
'quot': '"'
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// map UPPERCASE variants of supported special chars
|
|
26
|
+
Object.keys(ENTITY_MAPPING).forEach(function (k) {
|
|
27
|
+
ENTITY_MAPPING[k.toUpperCase()] = ENTITY_MAPPING[k];
|
|
28
|
+
});
|
|
29
|
+
function replaceEntities(_, d, x, z) {
|
|
30
|
+
// reserved names, i.e.
|
|
31
|
+
if (z) {
|
|
32
|
+
if (hasOwnProperty.call(ENTITY_MAPPING, z)) {
|
|
33
|
+
return ENTITY_MAPPING[z];
|
|
34
|
+
} else {
|
|
35
|
+
// fall back to original value
|
|
36
|
+
return '&' + z + ';';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// decimal encoded char
|
|
41
|
+
if (d) {
|
|
42
|
+
return fromCharCode(d);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// hex encoded char
|
|
46
|
+
return fromCharCode(parseInt(x, 16));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A basic entity decoder that can decode a minimal
|
|
51
|
+
* sub-set of reserved names (&) as well as
|
|
52
|
+
* hex (ય) and decimal (ӏ) encoded characters.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} s
|
|
55
|
+
*
|
|
56
|
+
* @return {string} decoded string
|
|
57
|
+
*/
|
|
58
|
+
function decodeEntities(s) {
|
|
59
|
+
if (s.length > 3 && s.indexOf('&') !== -1) {
|
|
60
|
+
return s.replace(ENTITY_PATTERN, replaceEntities);
|
|
61
|
+
}
|
|
62
|
+
return s;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Copy-pasted from file: parser.js
|
|
66
|
+
|
|
67
|
+
var NON_WHITESPACE_OUTSIDE_ROOT_NODE = 'non-whitespace outside of root node';
|
|
68
|
+
function error(msg) {
|
|
69
|
+
return new Error(msg);
|
|
70
|
+
}
|
|
71
|
+
function missingNamespaceForPrefix(prefix) {
|
|
72
|
+
return 'missing namespace for prefix <' + prefix + '>';
|
|
73
|
+
}
|
|
74
|
+
function getter(getFn) {
|
|
75
|
+
return {
|
|
76
|
+
'get': getFn,
|
|
77
|
+
'enumerable': true
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function cloneNsMatrix(nsMatrix) {
|
|
81
|
+
var clone = {},
|
|
82
|
+
key;
|
|
83
|
+
for (key in nsMatrix) {
|
|
84
|
+
clone[key] = nsMatrix[key];
|
|
85
|
+
}
|
|
86
|
+
return clone;
|
|
87
|
+
}
|
|
88
|
+
function uriPrefix(prefix) {
|
|
89
|
+
return prefix + '$uri';
|
|
90
|
+
}
|
|
91
|
+
function buildNsMatrix(nsUriToPrefix) {
|
|
92
|
+
var nsMatrix = {},
|
|
93
|
+
uri,
|
|
94
|
+
prefix;
|
|
95
|
+
for (uri in nsUriToPrefix) {
|
|
96
|
+
prefix = nsUriToPrefix[uri];
|
|
97
|
+
nsMatrix[prefix] = prefix;
|
|
98
|
+
nsMatrix[uriPrefix(prefix)] = uri;
|
|
99
|
+
}
|
|
100
|
+
return nsMatrix;
|
|
101
|
+
}
|
|
102
|
+
function noopGetContext() {
|
|
103
|
+
return {
|
|
104
|
+
line: 0,
|
|
105
|
+
column: 0
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function throwFunc(err) {
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Creates a new parser with the given options.
|
|
114
|
+
*
|
|
115
|
+
* @constructor
|
|
116
|
+
*
|
|
117
|
+
* @param {!Object<string, ?>=} options
|
|
118
|
+
*/
|
|
119
|
+
function Parser(options) {
|
|
120
|
+
if (!this) {
|
|
121
|
+
return new Parser(options);
|
|
122
|
+
}
|
|
123
|
+
var proxy = options && options['proxy'];
|
|
124
|
+
var onText,
|
|
125
|
+
onOpenTag,
|
|
126
|
+
onCloseTag,
|
|
127
|
+
onCDATA,
|
|
128
|
+
onError = throwFunc,
|
|
129
|
+
onWarning,
|
|
130
|
+
onComment,
|
|
131
|
+
onQuestion,
|
|
132
|
+
onAttention;
|
|
133
|
+
var getContext = noopGetContext;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Do we need to parse the current elements attributes for namespaces?
|
|
137
|
+
*
|
|
138
|
+
* @type {boolean}
|
|
139
|
+
*/
|
|
140
|
+
var maybeNS = false;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Do we process namespaces at all?
|
|
144
|
+
*
|
|
145
|
+
* @type {boolean}
|
|
146
|
+
*/
|
|
147
|
+
var isNamespace = false;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The caught error returned on parse end
|
|
151
|
+
*
|
|
152
|
+
* @type {Error}
|
|
153
|
+
*/
|
|
154
|
+
var returnError = null;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Should we stop parsing?
|
|
158
|
+
*
|
|
159
|
+
* @type {boolean}
|
|
160
|
+
*/
|
|
161
|
+
var parseStop = false;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* A map of { uri: prefix } used by the parser.
|
|
165
|
+
*
|
|
166
|
+
* This map will ensure we can normalize prefixes during processing;
|
|
167
|
+
* for each uri, only one prefix will be exposed to the handlers.
|
|
168
|
+
*
|
|
169
|
+
* @type {!Object<string, string>}}
|
|
170
|
+
*/
|
|
171
|
+
var nsUriToPrefix;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Handle parse error.
|
|
175
|
+
*
|
|
176
|
+
* @param {string|Error} err
|
|
177
|
+
*/
|
|
178
|
+
function handleError(err) {
|
|
179
|
+
if (!(err instanceof Error)) {
|
|
180
|
+
err = error(err);
|
|
181
|
+
}
|
|
182
|
+
returnError = err;
|
|
183
|
+
onError(err, getContext);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Handle parse error.
|
|
188
|
+
*
|
|
189
|
+
* @param {string|Error} err
|
|
190
|
+
*/
|
|
191
|
+
function handleWarning(err) {
|
|
192
|
+
if (!onWarning) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (!(err instanceof Error)) {
|
|
196
|
+
err = error(err);
|
|
197
|
+
}
|
|
198
|
+
onWarning(err, getContext);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Register parse listener.
|
|
203
|
+
*
|
|
204
|
+
* @param {string} name
|
|
205
|
+
* @param {Function} cb
|
|
206
|
+
*
|
|
207
|
+
* @return {Parser}
|
|
208
|
+
*/
|
|
209
|
+
this['on'] = function (name, cb) {
|
|
210
|
+
if (typeof cb !== 'function') {
|
|
211
|
+
throw error('required args <name, cb>');
|
|
212
|
+
}
|
|
213
|
+
switch (name) {
|
|
214
|
+
case 'openTag':
|
|
215
|
+
onOpenTag = cb;
|
|
216
|
+
break;
|
|
217
|
+
case 'text':
|
|
218
|
+
onText = cb;
|
|
219
|
+
break;
|
|
220
|
+
case 'closeTag':
|
|
221
|
+
onCloseTag = cb;
|
|
222
|
+
break;
|
|
223
|
+
case 'error':
|
|
224
|
+
onError = cb;
|
|
225
|
+
break;
|
|
226
|
+
case 'warn':
|
|
227
|
+
onWarning = cb;
|
|
228
|
+
break;
|
|
229
|
+
case 'cdata':
|
|
230
|
+
onCDATA = cb;
|
|
231
|
+
break;
|
|
232
|
+
case 'attention':
|
|
233
|
+
onAttention = cb;
|
|
234
|
+
break;
|
|
235
|
+
// <!XXXXX zzzz="eeee">
|
|
236
|
+
case 'question':
|
|
237
|
+
onQuestion = cb;
|
|
238
|
+
break;
|
|
239
|
+
// <? .... ?>
|
|
240
|
+
case 'comment':
|
|
241
|
+
onComment = cb;
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
throw error('unsupported event: ' + name);
|
|
245
|
+
}
|
|
246
|
+
return this;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Set the namespace to prefix mapping.
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
*
|
|
254
|
+
* parser.ns({
|
|
255
|
+
* 'http://foo': 'foo',
|
|
256
|
+
* 'http://bar': 'bar'
|
|
257
|
+
* });
|
|
258
|
+
*
|
|
259
|
+
* @param {!Object<string, string>} nsMap
|
|
260
|
+
*
|
|
261
|
+
* @return {Parser}
|
|
262
|
+
*/
|
|
263
|
+
this['ns'] = function (nsMap) {
|
|
264
|
+
if (typeof nsMap === 'undefined') {
|
|
265
|
+
nsMap = {};
|
|
266
|
+
}
|
|
267
|
+
if (_typeof(nsMap) !== 'object') {
|
|
268
|
+
throw error('required args <nsMap={}>');
|
|
269
|
+
}
|
|
270
|
+
var _nsUriToPrefix = {},
|
|
271
|
+
k;
|
|
272
|
+
for (k in nsMap) {
|
|
273
|
+
_nsUriToPrefix[k] = nsMap[k];
|
|
274
|
+
}
|
|
275
|
+
isNamespace = true;
|
|
276
|
+
nsUriToPrefix = _nsUriToPrefix;
|
|
277
|
+
return this;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Parse xml string.
|
|
282
|
+
*
|
|
283
|
+
* @param {string} xml
|
|
284
|
+
*
|
|
285
|
+
* @return {Error} returnError, if not thrown
|
|
286
|
+
*/
|
|
287
|
+
this['parse'] = function (xml) {
|
|
288
|
+
if (typeof xml !== 'string') {
|
|
289
|
+
throw error('required args <xml=string>');
|
|
290
|
+
}
|
|
291
|
+
returnError = null;
|
|
292
|
+
parse(xml);
|
|
293
|
+
getContext = noopGetContext;
|
|
294
|
+
parseStop = false;
|
|
295
|
+
return returnError;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Stop parsing.
|
|
300
|
+
*/
|
|
301
|
+
this['stop'] = function () {
|
|
302
|
+
parseStop = true;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Parse string, invoking configured listeners on element.
|
|
307
|
+
*
|
|
308
|
+
* @param {string} xml
|
|
309
|
+
*/
|
|
310
|
+
function parse(xml) {
|
|
311
|
+
var nsMatrixStack = isNamespace ? [] : null,
|
|
312
|
+
nsMatrix = isNamespace ? buildNsMatrix(nsUriToPrefix) : null,
|
|
313
|
+
_nsMatrix,
|
|
314
|
+
nodeStack = [],
|
|
315
|
+
anonymousNsCount = 0,
|
|
316
|
+
tagStart = false,
|
|
317
|
+
tagEnd = false,
|
|
318
|
+
i = 0,
|
|
319
|
+
j = 0,
|
|
320
|
+
x,
|
|
321
|
+
y,
|
|
322
|
+
q,
|
|
323
|
+
w,
|
|
324
|
+
v,
|
|
325
|
+
xmlns,
|
|
326
|
+
elementName,
|
|
327
|
+
_elementName,
|
|
328
|
+
elementProxy;
|
|
329
|
+
var attrsString = '',
|
|
330
|
+
attrsStart = 0,
|
|
331
|
+
cachedAttrs // false = parsed with errors, null = needs parsing
|
|
332
|
+
;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Parse attributes on demand and returns the parsed attributes.
|
|
336
|
+
*
|
|
337
|
+
* Return semantics: (1) `false` on attribute parse error,
|
|
338
|
+
* (2) object hash on extracted attrs.
|
|
339
|
+
*
|
|
340
|
+
* @return {boolean|Object}
|
|
341
|
+
*/
|
|
342
|
+
function getAttrs() {
|
|
343
|
+
if (cachedAttrs !== null) {
|
|
344
|
+
return cachedAttrs;
|
|
345
|
+
}
|
|
346
|
+
var nsUri,
|
|
347
|
+
nsUriPrefix,
|
|
348
|
+
nsName,
|
|
349
|
+
defaultAlias = isNamespace && nsMatrix['xmlns'],
|
|
350
|
+
attrList = isNamespace && maybeNS ? [] : null,
|
|
351
|
+
i = attrsStart,
|
|
352
|
+
s = attrsString,
|
|
353
|
+
l = s.length,
|
|
354
|
+
hasNewMatrix,
|
|
355
|
+
newalias,
|
|
356
|
+
value,
|
|
357
|
+
alias,
|
|
358
|
+
name,
|
|
359
|
+
attrs = {},
|
|
360
|
+
seenAttrs = {},
|
|
361
|
+
skipAttr,
|
|
362
|
+
w,
|
|
363
|
+
j;
|
|
364
|
+
parseAttr: for (; i < l; i++) {
|
|
365
|
+
skipAttr = false;
|
|
366
|
+
w = s.charCodeAt(i);
|
|
367
|
+
if (w === 32 || w < 14 && w > 8) {
|
|
368
|
+
// WHITESPACE={ \f\n\r\t\v}
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// wait for non whitespace character
|
|
373
|
+
if (w < 65 || w > 122 || w > 90 && w < 97) {
|
|
374
|
+
if (w !== 95 && w !== 58) {
|
|
375
|
+
// char 95"_" 58":"
|
|
376
|
+
handleWarning('illegal first char attribute name');
|
|
377
|
+
skipAttr = true;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// parse attribute name
|
|
382
|
+
for (j = i + 1; j < l; j++) {
|
|
383
|
+
w = s.charCodeAt(j);
|
|
384
|
+
if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 46 ||
|
|
385
|
+
// '.'
|
|
386
|
+
w === 45 ||
|
|
387
|
+
// '-'
|
|
388
|
+
w === 95 // '_'
|
|
389
|
+
) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// unexpected whitespace
|
|
394
|
+
if (w === 32 || w < 14 && w > 8) {
|
|
395
|
+
// WHITESPACE
|
|
396
|
+
handleWarning('missing attribute value');
|
|
397
|
+
i = j;
|
|
398
|
+
continue parseAttr;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// expected "="
|
|
402
|
+
if (w === 61) {
|
|
403
|
+
// "=" == 61
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
handleWarning('illegal attribute name char');
|
|
407
|
+
skipAttr = true;
|
|
408
|
+
}
|
|
409
|
+
name = s.substring(i, j);
|
|
410
|
+
if (name === 'xmlns:xmlns') {
|
|
411
|
+
handleWarning('illegal declaration of xmlns');
|
|
412
|
+
skipAttr = true;
|
|
413
|
+
}
|
|
414
|
+
w = s.charCodeAt(j + 1);
|
|
415
|
+
if (w === 34) {
|
|
416
|
+
// '"'
|
|
417
|
+
j = s.indexOf('"', i = j + 2);
|
|
418
|
+
if (j === -1) {
|
|
419
|
+
j = s.indexOf('\'', i);
|
|
420
|
+
if (j !== -1) {
|
|
421
|
+
handleWarning('attribute value quote missmatch');
|
|
422
|
+
skipAttr = true;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
} else if (w === 39) {
|
|
426
|
+
// "'"
|
|
427
|
+
j = s.indexOf('\'', i = j + 2);
|
|
428
|
+
if (j === -1) {
|
|
429
|
+
j = s.indexOf('"', i);
|
|
430
|
+
if (j !== -1) {
|
|
431
|
+
handleWarning('attribute value quote missmatch');
|
|
432
|
+
skipAttr = true;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
} else {
|
|
436
|
+
handleWarning('missing attribute value quotes');
|
|
437
|
+
skipAttr = true;
|
|
438
|
+
|
|
439
|
+
// skip to next space
|
|
440
|
+
for (j = j + 1; j < l; j++) {
|
|
441
|
+
w = s.charCodeAt(j + 1);
|
|
442
|
+
if (w === 32 || w < 14 && w > 8) {
|
|
443
|
+
// WHITESPACE
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (j === -1) {
|
|
449
|
+
handleWarning('missing closing quotes');
|
|
450
|
+
j = l;
|
|
451
|
+
skipAttr = true;
|
|
452
|
+
}
|
|
453
|
+
if (!skipAttr) {
|
|
454
|
+
value = s.substring(i, j);
|
|
455
|
+
}
|
|
456
|
+
i = j;
|
|
457
|
+
|
|
458
|
+
// ensure SPACE follows attribute
|
|
459
|
+
// skip illegal content otherwise
|
|
460
|
+
// example a="b"c
|
|
461
|
+
for (; j + 1 < l; j++) {
|
|
462
|
+
w = s.charCodeAt(j + 1);
|
|
463
|
+
if (w === 32 || w < 14 && w > 8) {
|
|
464
|
+
// WHITESPACE
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// FIRST ILLEGAL CHAR
|
|
469
|
+
if (i === j) {
|
|
470
|
+
handleWarning('illegal character after attribute end');
|
|
471
|
+
skipAttr = true;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// advance cursor to next attribute
|
|
476
|
+
i = j + 1;
|
|
477
|
+
if (skipAttr) {
|
|
478
|
+
continue parseAttr;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// check attribute re-declaration
|
|
482
|
+
if (name in seenAttrs) {
|
|
483
|
+
handleWarning('attribute <' + name + '> already defined');
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
seenAttrs[name] = true;
|
|
487
|
+
if (!isNamespace) {
|
|
488
|
+
attrs[name] = value;
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// try to extract namespace information
|
|
493
|
+
if (maybeNS) {
|
|
494
|
+
newalias = name === 'xmlns' ? 'xmlns' : name.charCodeAt(0) === 120 && name.substr(0, 6) === 'xmlns:' ? name.substr(6) : null;
|
|
495
|
+
|
|
496
|
+
// handle xmlns(:alias) assignment
|
|
497
|
+
if (newalias !== null) {
|
|
498
|
+
nsUri = decodeEntities(value);
|
|
499
|
+
nsUriPrefix = uriPrefix(newalias);
|
|
500
|
+
alias = nsUriToPrefix[nsUri];
|
|
501
|
+
if (!alias) {
|
|
502
|
+
// no prefix defined or prefix collision
|
|
503
|
+
if (newalias === 'xmlns' || nsUriPrefix in nsMatrix && nsMatrix[nsUriPrefix] !== nsUri) {
|
|
504
|
+
// alocate free ns prefix
|
|
505
|
+
do {
|
|
506
|
+
alias = 'ns' + anonymousNsCount++;
|
|
507
|
+
} while (typeof nsMatrix[alias] !== 'undefined');
|
|
508
|
+
} else {
|
|
509
|
+
alias = newalias;
|
|
510
|
+
}
|
|
511
|
+
nsUriToPrefix[nsUri] = alias;
|
|
512
|
+
}
|
|
513
|
+
if (nsMatrix[newalias] !== alias) {
|
|
514
|
+
if (!hasNewMatrix) {
|
|
515
|
+
nsMatrix = cloneNsMatrix(nsMatrix);
|
|
516
|
+
hasNewMatrix = true;
|
|
517
|
+
}
|
|
518
|
+
nsMatrix[newalias] = alias;
|
|
519
|
+
if (newalias === 'xmlns') {
|
|
520
|
+
nsMatrix[uriPrefix(alias)] = nsUri;
|
|
521
|
+
defaultAlias = alias;
|
|
522
|
+
}
|
|
523
|
+
nsMatrix[nsUriPrefix] = nsUri;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// expose xmlns(:asd)="..." in attributes
|
|
527
|
+
attrs[name] = value;
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// collect attributes until all namespace
|
|
532
|
+
// declarations are processed
|
|
533
|
+
attrList.push(name, value);
|
|
534
|
+
continue;
|
|
535
|
+
} /** end if (maybeNs) */
|
|
536
|
+
|
|
537
|
+
// handle attributes on element without
|
|
538
|
+
// namespace declarations
|
|
539
|
+
w = name.indexOf(':');
|
|
540
|
+
if (w === -1) {
|
|
541
|
+
attrs[name] = value;
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// normalize ns attribute name
|
|
546
|
+
if (!(nsName = nsMatrix[name.substring(0, w)])) {
|
|
547
|
+
handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w);
|
|
551
|
+
|
|
552
|
+
// end: normalize ns attribute name
|
|
553
|
+
|
|
554
|
+
attrs[name] = value;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// handle deferred, possibly namespaced attributes
|
|
558
|
+
if (maybeNS) {
|
|
559
|
+
// normalize captured attributes
|
|
560
|
+
for (i = 0, l = attrList.length; i < l; i++) {
|
|
561
|
+
name = attrList[i++];
|
|
562
|
+
value = attrList[i];
|
|
563
|
+
w = name.indexOf(':');
|
|
564
|
+
if (w !== -1) {
|
|
565
|
+
// normalize ns attribute name
|
|
566
|
+
if (!(nsName = nsMatrix[name.substring(0, w)])) {
|
|
567
|
+
handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w);
|
|
571
|
+
|
|
572
|
+
// end: normalize ns attribute name
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
attrs[name] = value;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// end: normalize captured attributes
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
return cachedAttrs = attrs;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Extract the parse context { line, column, part }
|
|
586
|
+
* from the current parser position.
|
|
587
|
+
*
|
|
588
|
+
* @return {Object} parse context
|
|
589
|
+
*/
|
|
590
|
+
function getParseContext() {
|
|
591
|
+
var splitsRe = /(\r\n|\r|\n)/g;
|
|
592
|
+
var line = 0;
|
|
593
|
+
var column = 0;
|
|
594
|
+
var startOfLine = 0;
|
|
595
|
+
var endOfLine = j;
|
|
596
|
+
var match;
|
|
597
|
+
var data;
|
|
598
|
+
while (i >= startOfLine) {
|
|
599
|
+
match = splitsRe.exec(xml);
|
|
600
|
+
if (!match) {
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// end of line = (break idx + break chars)
|
|
605
|
+
endOfLine = match[0].length + match.index;
|
|
606
|
+
if (endOfLine > i) {
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// advance to next line
|
|
611
|
+
line += 1;
|
|
612
|
+
startOfLine = endOfLine;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// EOF errors
|
|
616
|
+
if (i == -1) {
|
|
617
|
+
column = endOfLine;
|
|
618
|
+
data = xml.substring(j);
|
|
619
|
+
} else
|
|
620
|
+
// start errors
|
|
621
|
+
if (j === 0) {
|
|
622
|
+
data = xml.substring(j, i);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// other errors
|
|
626
|
+
else {
|
|
627
|
+
column = i - startOfLine;
|
|
628
|
+
data = j == -1 ? xml.substring(i) : xml.substring(i, j + 1);
|
|
629
|
+
}
|
|
630
|
+
return {
|
|
631
|
+
'data': data,
|
|
632
|
+
'line': line,
|
|
633
|
+
'column': column
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
getContext = getParseContext;
|
|
637
|
+
if (proxy) {
|
|
638
|
+
elementProxy = Object.create({}, {
|
|
639
|
+
'name': getter(function () {
|
|
640
|
+
return elementName;
|
|
641
|
+
}),
|
|
642
|
+
'originalName': getter(function () {
|
|
643
|
+
return _elementName;
|
|
644
|
+
}),
|
|
645
|
+
'attrs': getter(getAttrs),
|
|
646
|
+
'ns': getter(function () {
|
|
647
|
+
return nsMatrix;
|
|
648
|
+
})
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// actual parse logic
|
|
653
|
+
while (j !== -1) {
|
|
654
|
+
if (xml.charCodeAt(j) === 60) {
|
|
655
|
+
// "<"
|
|
656
|
+
i = j;
|
|
657
|
+
} else {
|
|
658
|
+
i = xml.indexOf('<', j);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// parse end
|
|
662
|
+
if (i === -1) {
|
|
663
|
+
if (nodeStack.length) {
|
|
664
|
+
return handleError('unexpected end of file');
|
|
665
|
+
}
|
|
666
|
+
if (j === 0) {
|
|
667
|
+
return handleError('missing start tag');
|
|
668
|
+
}
|
|
669
|
+
if (j < xml.length) {
|
|
670
|
+
if (xml.substring(j).trim()) {
|
|
671
|
+
handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// parse text
|
|
678
|
+
if (j !== i) {
|
|
679
|
+
if (nodeStack.length) {
|
|
680
|
+
if (onText) {
|
|
681
|
+
onText(xml.substring(j, i), decodeEntities, getContext);
|
|
682
|
+
if (parseStop) {
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
} else {
|
|
687
|
+
if (xml.substring(j, i).trim()) {
|
|
688
|
+
handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
|
|
689
|
+
if (parseStop) {
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
w = xml.charCodeAt(i + 1);
|
|
696
|
+
|
|
697
|
+
// parse comments + CDATA
|
|
698
|
+
if (w === 33) {
|
|
699
|
+
// "!"
|
|
700
|
+
q = xml.charCodeAt(i + 2);
|
|
701
|
+
|
|
702
|
+
// CDATA section
|
|
703
|
+
if (q === 91 && xml.substr(i + 3, 6) === 'CDATA[') {
|
|
704
|
+
// 91 == "["
|
|
705
|
+
j = xml.indexOf(']]>', i);
|
|
706
|
+
if (j === -1) {
|
|
707
|
+
return handleError('unclosed cdata');
|
|
708
|
+
}
|
|
709
|
+
if (onCDATA) {
|
|
710
|
+
onCDATA(xml.substring(i + 9, j), getContext);
|
|
711
|
+
if (parseStop) {
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
j += 3;
|
|
716
|
+
continue;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// comment
|
|
720
|
+
if (q === 45 && xml.charCodeAt(i + 3) === 45) {
|
|
721
|
+
// 45 == "-"
|
|
722
|
+
j = xml.indexOf('-->', i);
|
|
723
|
+
if (j === -1) {
|
|
724
|
+
return handleError('unclosed comment');
|
|
725
|
+
}
|
|
726
|
+
if (onComment) {
|
|
727
|
+
onComment(xml.substring(i + 4, j), decodeEntities, getContext);
|
|
728
|
+
if (parseStop) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
j += 3;
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// parse question <? ... ?>
|
|
738
|
+
if (w === 63) {
|
|
739
|
+
// "?"
|
|
740
|
+
j = xml.indexOf('?>', i);
|
|
741
|
+
if (j === -1) {
|
|
742
|
+
return handleError('unclosed question');
|
|
743
|
+
}
|
|
744
|
+
if (onQuestion) {
|
|
745
|
+
onQuestion(xml.substring(i, j + 2), getContext);
|
|
746
|
+
if (parseStop) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
j += 2;
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// find matching closing tag for attention or standard tags
|
|
755
|
+
// for that we must skip through attribute values
|
|
756
|
+
// (enclosed in single or double quotes)
|
|
757
|
+
for (x = i + 1;; x++) {
|
|
758
|
+
v = xml.charCodeAt(x);
|
|
759
|
+
if (isNaN(v)) {
|
|
760
|
+
j = -1;
|
|
761
|
+
return handleError('unclosed tag');
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
|
|
765
|
+
// skips the quoted string
|
|
766
|
+
// (double quotes) does not appear in a literal enclosed by (double quotes)
|
|
767
|
+
// (single quote) does not appear in a literal enclosed by (single quote)
|
|
768
|
+
if (v === 34) {
|
|
769
|
+
// '"'
|
|
770
|
+
q = xml.indexOf('"', x + 1);
|
|
771
|
+
x = q !== -1 ? q : x;
|
|
772
|
+
} else if (v === 39) {
|
|
773
|
+
// "'"
|
|
774
|
+
q = xml.indexOf("'", x + 1);
|
|
775
|
+
x = q !== -1 ? q : x;
|
|
776
|
+
} else if (v === 62) {
|
|
777
|
+
// '>'
|
|
778
|
+
j = x;
|
|
779
|
+
break;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// parse attention <! ...>
|
|
784
|
+
// previously comment and CDATA have already been parsed
|
|
785
|
+
if (w === 33) {
|
|
786
|
+
// "!"
|
|
787
|
+
|
|
788
|
+
if (onAttention) {
|
|
789
|
+
onAttention(xml.substring(i, j + 1), decodeEntities, getContext);
|
|
790
|
+
if (parseStop) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
j += 1;
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// don't process attributes;
|
|
799
|
+
// there are none
|
|
800
|
+
cachedAttrs = {};
|
|
801
|
+
|
|
802
|
+
// if (xml.charCodeAt(i+1) === 47) { // </...
|
|
803
|
+
if (w === 47) {
|
|
804
|
+
// </...
|
|
805
|
+
tagStart = false;
|
|
806
|
+
tagEnd = true;
|
|
807
|
+
if (!nodeStack.length) {
|
|
808
|
+
return handleError('missing open tag');
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// verify open <-> close tag match
|
|
812
|
+
x = elementName = nodeStack.pop();
|
|
813
|
+
q = i + 2 + x.length;
|
|
814
|
+
if (xml.substring(i + 2, q) !== x) {
|
|
815
|
+
return handleError('closing tag mismatch');
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// verify chars in close tag
|
|
819
|
+
for (; q < j; q++) {
|
|
820
|
+
w = xml.charCodeAt(q);
|
|
821
|
+
if (w === 32 || w > 8 && w < 14) {
|
|
822
|
+
// \f\n\r\t\v space
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
return handleError('close tag');
|
|
826
|
+
}
|
|
827
|
+
} else {
|
|
828
|
+
if (xml.charCodeAt(j - 1) === 47) {
|
|
829
|
+
// .../>
|
|
830
|
+
x = elementName = xml.substring(i + 1, j - 1);
|
|
831
|
+
tagStart = true;
|
|
832
|
+
tagEnd = true;
|
|
833
|
+
} else {
|
|
834
|
+
x = elementName = xml.substring(i + 1, j);
|
|
835
|
+
tagStart = true;
|
|
836
|
+
tagEnd = false;
|
|
837
|
+
}
|
|
838
|
+
if (!(w > 96 && w < 123 || w > 64 && w < 91 || w === 95 || w === 58)) {
|
|
839
|
+
// char 95"_" 58":"
|
|
840
|
+
return handleError('illegal first char nodeName');
|
|
841
|
+
}
|
|
842
|
+
for (q = 1, y = x.length; q < y; q++) {
|
|
843
|
+
w = x.charCodeAt(q);
|
|
844
|
+
if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w == 46) {
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
if (w === 32 || w < 14 && w > 8) {
|
|
848
|
+
// \f\n\r\t\v space
|
|
849
|
+
elementName = x.substring(0, q);
|
|
850
|
+
|
|
851
|
+
// maybe there are attributes
|
|
852
|
+
cachedAttrs = null;
|
|
853
|
+
break;
|
|
854
|
+
}
|
|
855
|
+
return handleError('invalid nodeName');
|
|
856
|
+
}
|
|
857
|
+
if (!tagEnd) {
|
|
858
|
+
nodeStack.push(elementName);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
if (isNamespace) {
|
|
862
|
+
_nsMatrix = nsMatrix;
|
|
863
|
+
if (tagStart) {
|
|
864
|
+
// remember old namespace
|
|
865
|
+
// unless we're self-closing
|
|
866
|
+
if (!tagEnd) {
|
|
867
|
+
nsMatrixStack.push(_nsMatrix);
|
|
868
|
+
}
|
|
869
|
+
if (cachedAttrs === null) {
|
|
870
|
+
// quick check, whether there may be namespace
|
|
871
|
+
// declarations on the node; if that is the case
|
|
872
|
+
// we need to eagerly parse the node attributes
|
|
873
|
+
if (maybeNS = x.indexOf('xmlns', q) !== -1) {
|
|
874
|
+
attrsStart = q;
|
|
875
|
+
attrsString = x;
|
|
876
|
+
getAttrs();
|
|
877
|
+
maybeNS = false;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
_elementName = elementName;
|
|
882
|
+
w = elementName.indexOf(':');
|
|
883
|
+
if (w !== -1) {
|
|
884
|
+
xmlns = nsMatrix[elementName.substring(0, w)];
|
|
885
|
+
|
|
886
|
+
// prefix given; namespace must exist
|
|
887
|
+
if (!xmlns) {
|
|
888
|
+
return handleError('missing namespace on <' + _elementName + '>');
|
|
889
|
+
}
|
|
890
|
+
elementName = elementName.substr(w + 1);
|
|
891
|
+
} else {
|
|
892
|
+
xmlns = nsMatrix['xmlns'];
|
|
893
|
+
|
|
894
|
+
// if no default namespace is defined,
|
|
895
|
+
// we'll import the element as anonymous.
|
|
896
|
+
//
|
|
897
|
+
// it is up to users to correct that to the document defined
|
|
898
|
+
// targetNamespace, or whatever their undersanding of the
|
|
899
|
+
// XML spec mandates.
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// adjust namespace prefixs as configured
|
|
903
|
+
if (xmlns) {
|
|
904
|
+
elementName = xmlns + ':' + elementName;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
if (tagStart) {
|
|
908
|
+
attrsStart = q;
|
|
909
|
+
attrsString = x;
|
|
910
|
+
if (onOpenTag) {
|
|
911
|
+
if (proxy) {
|
|
912
|
+
onOpenTag(elementProxy, decodeEntities, tagEnd, getContext);
|
|
913
|
+
} else {
|
|
914
|
+
onOpenTag(elementName, getAttrs, decodeEntities, tagEnd, getContext);
|
|
915
|
+
}
|
|
916
|
+
if (parseStop) {
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
if (tagEnd) {
|
|
922
|
+
if (onCloseTag) {
|
|
923
|
+
onCloseTag(proxy ? elementProxy : elementName, decodeEntities, tagStart, getContext);
|
|
924
|
+
if (parseStop) {
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
// restore old namespace
|
|
930
|
+
if (isNamespace) {
|
|
931
|
+
if (!tagStart) {
|
|
932
|
+
nsMatrix = nsMatrixStack.pop();
|
|
933
|
+
} else {
|
|
934
|
+
nsMatrix = _nsMatrix;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
j += 1;
|
|
939
|
+
}
|
|
940
|
+
} /** end parse */
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// Returns:
|
|
944
|
+
|
|
945
|
+
return Parser(options);
|
|
946
|
+
}
|
|
947
|
+
//# sourceMappingURL=parseXmlStream.saxen.code.js.map
|