xml-twig 1.9.3 → 1.10.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 CHANGED
@@ -20,7 +20,7 @@ When you need to read an XML file, there are two primary approaches:
20
20
  This module aims to combine both approaches. It reads the XML document in chunks, and within each chunk, you can utilize the familiar features and functions of a DOM-based parser.
21
21
 
22
22
  ## Dependencies
23
- XML documents are parsed using either the [sax](https://www.npmjs.com/package/sax) or [node-expat](https://www.npmjs.com/package/node-expat) parser. parsers. Additional parsers may be added in future releases. By default, the `sax` parser is used. However, I strongly recommend using the `node-expat` parser, as other parsers I tested are not fully compliant with XML standards.
23
+ XML documents are parsed using either the [sax](https://www.npmjs.com/package/sax) or [node-expat](https://www.npmjs.com/package/node-expat) parser. parsers. Additional parsers may be added in future releases. By default, the `sax` parser is used. However, I recommend using the `node-expat` parser, which is faster more compliant with XML standards.
24
24
 
25
25
  **NOTE: The `node-expat` module is not automatically installed with this module. If you wish to use it, you must install it manually.**
26
26
 
@@ -57,6 +57,10 @@ API Documentation: see [Twig](./doc/twig.md)
57
57
  const parser = twig.createParser({ tag: twig.Root, function: rootHandler }, { method: 'sax' })
58
58
  fs.createReadStream(`${__dirname}/bookstore.xml`).pipe(parser)
59
59
 
60
+ parser.on('error', function (err) {
61
+ console.error(err);
62
+ });
63
+
60
64
  // Output -> <bookstore> finished after 48 lines
61
65
  ```
62
66
 
@@ -386,12 +390,5 @@ This `xml-twig` module focus on reading a XML files. In principle it would be po
386
390
 
387
391
  Accessing Twig-Elements by [XML-Path](https://www.w3.org/TR/xpath/) language is not supported. One reason it, the `Twig` class models more an [Element](https://www.w3schools.com/xml/xml_elements.asp) rather than a [Node](https://www.w3schools.com/xml/dom_nodes.asp) which would be more generic.
388
392
 
389
- As already mentioned above, I recommend the `expat` parser. The other parser may work for your purpose, however they have several limitations and bugs:
390
-
391
- - `sax` does not support UTF-16 encoding. I did not test other encodings, because [W3C Recommendations](https://www.w3.org/TR/xml/#charencoding) defines only UTF-8 and UTF-16 as required
392
- - `sax` misinterpret character entities
393
-
394
-
395
-
396
393
 
397
394
 
package/doc/twig.md CHANGED
@@ -1528,7 +1528,7 @@ Generic error for unsupported condition
1528
1528
 
1529
1529
  ## SAX
1530
1530
  **Kind**: global constant
1531
- **Version:**: 1.9.3
1531
+ **Version:**: 1.10.0
1532
1532
  **Author:**: Wernfried Domscheit
1533
1533
  **Copyright:**: Copyright (c) 2025 Wernfried Domscheit. All rights reserved.
1534
1534
  **Website:**: https://www.npmjs.com/package/xml-twig
@@ -1600,7 +1600,7 @@ Optional settings for the Twig parser
1600
1600
  | method | <code>&#x27;sax&#x27;</code> \| <code>&#x27;expat&#x27;</code> | The underlying parser. Either `'sax'`, `'expat'`. |
1601
1601
  | xmlns | <code>boolean</code> | If `true`, then namespaces are accessible by `namespace` property. |
1602
1602
  | trim | <code>boolean</code> | If `true`, then turn any whitespace into a single space. Text and comments are trimmed. |
1603
- | resumeAfterError | <code>boolean</code> | If `true` then parser continues reading after an error. Otherwise it throws exception. |
1603
+ | resumeAfterError | <code>boolean</code> | If `true` then parser continues reading after an error.<br> Only relevant for `sax`, `expat` always terminates on error. |
1604
1604
  | partial | <code>boolean</code> | If `true` then unhandled elements are purged. |
1605
1605
  | file | <code>string</code> | Optional. The name of file to be parsed. Just used for information and logging purpose. |
1606
1606
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "name": "xml-twig",
7
7
  "description": "Node module for processing huge XML documents in tree mode",
8
- "version": "1.9.3",
8
+ "version": "1.10.0",
9
9
  "main": "twig.js",
10
10
  "directories": {
11
11
  "doc": "doc"
package/twig.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @version: 1.9.3
2
+ * @version: 1.10.0
3
3
  * @author: Wernfried Domscheit
4
4
  * @copyright: Copyright (c) 2025 Wernfried Domscheit. All rights reserved.
5
5
  * @website: https://www.npmjs.com/package/xml-twig
@@ -65,7 +65,8 @@ const Any = new AnyHandler();
65
65
  * @property {'sax' | 'expat'} method - The underlying parser. Either `'sax'`, `'expat'`.
66
66
  * @property {boolean} xmlns - If `true`, then namespaces are accessible by `namespace` property.
67
67
  * @property {boolean} trim - If `true`, then turn any whitespace into a single space. Text and comments are trimmed.
68
- * @property {boolean} resumeAfterError - If `true` then parser continues reading after an error. Otherwise it throws exception.
68
+ * @property {boolean} resumeAfterError - If `true` then parser continues reading after an error.<br>
69
+ * Only relevant for `sax`, `expat` always terminates on error.
69
70
  * @property {boolean} partial - If `true` then unhandled elements are purged.
70
71
  * @property {string} [file - Optional. The name of file to be parsed. Just used for information and logging purpose.
71
72
  * @example { method: 'expat', xmlns: true }
@@ -222,6 +223,15 @@ function createParser(handler, options = {}) {
222
223
  parser.emit("close");
223
224
  });
224
225
 
226
+ parser.on('error', function (err) {
227
+ if (options.resumeAfterError) {
228
+ parser._parser.error = null;
229
+ parser._parser.resume();
230
+ } else {
231
+ parser._parser.close();
232
+ }
233
+ });
234
+
225
235
  } else if (EXPAT.includes(options.method)) {
226
236
  parser = require("node-expat").createParser();
227
237
  Object.defineProperty(parser, 'currentLine', {
@@ -262,6 +272,13 @@ function createParser(handler, options = {}) {
262
272
  parser.emit("finish");
263
273
  });
264
274
 
275
+ parser.on('error', function (err) {
276
+ // convert 'err' string into Error object
277
+ if (typeof err === 'string')
278
+ parser.emit('error', Error(`${err}\nLine: ${parser.currentLine}\nColumn: ${parser.currentColumn}`))
279
+ // resume not supported
280
+ });
281
+
265
282
  } else {
266
283
  throw new UnsupportedParser(options.method);
267
284
  }
@@ -315,14 +332,6 @@ function createParser(handler, options = {}) {
315
332
  }
316
333
  });
317
334
 
318
- parser.on('error', function (err) {
319
- console.error(`error at line [${parser.currentLine}], column [${parser.currentColumn}]`, err);
320
- if (options.resumeAfterError) {
321
- parser.underlyingParser.error = null;
322
- parser.underlyingParser.resume();
323
- }
324
- });
325
-
326
335
  return parser;
327
336
  }
328
337