xml-twig 1.4.1 → 1.6.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
@@ -48,8 +48,8 @@ API Documentation: see [Twig](./doc/twig.md)
48
48
  const fs = require('fs')
49
49
  const twig = require('xml-twig')
50
50
 
51
- function rootHandler(elt) {
52
- console.log(`<${elt.name}> finished after ${parser.currentLine} lines`);
51
+ function rootHandler(elt, parserObj) {
52
+ console.log(`<${elt.name}> finished after ${parserObj.currentLine} lines`);
53
53
  }
54
54
 
55
55
  const parser = twig.createParser({ tag: twig.Root, function: rootHandler }, { method: 'sax' })
@@ -78,8 +78,8 @@ API Documentation: see [Twig](./doc/twig.md)
78
78
 
79
79
 
80
80
  ```js
81
- function bookHandler(elt) {
82
- console.log(`${elt.attr("category")} ${elt.name} at line ${parser.currentLine}`)
81
+ function bookHandler(elt, parserObj) {
82
+ console.log(`${elt.attr("category")} ${elt.name} at line ${parserObj.currentLine}`)
83
83
  elt.purge() // -> without `purge()` the entire XML document will be loaded into memory
84
84
  }
85
85
 
@@ -119,8 +119,8 @@ API Documentation: see [Twig](./doc/twig.md)
119
119
  - **Read every element from XML Document**
120
120
 
121
121
  ```js
122
- function anyHandler(elt) {
123
- console.log(`${' '.repeat(elt.level)}${elt.name} => "${elt.text ?? ''}" at line ${parser.currentLine}`)
122
+ function anyHandler(elt, parserObj) {
123
+ console.log(`${' '.repeat(elt.level)}${elt.name} => "${elt.text ?? ''}" at line ${parserObj.currentLine}`)
124
124
  elt.purge() // -> without `purge()` the entire XML document will be loaded into memory
125
125
  }
126
126
 
@@ -164,8 +164,8 @@ Be aware if you run methods like `elt.followingSibling()`, `elt.descendant()`, `
164
164
  const parser = twig.createParser(handle_ebook, { partial: true })
165
165
  fs.createReadStream(`${__dirname}/bookstore.xml`).pipe(parser);
166
166
 
167
- function ebookHandler(elt) {
168
- console.log(`${elt.name} at line ${parser.currentLine}`)
167
+ function ebookHandler(elt, parserObj) {
168
+ console.log(`${elt.name} at line ${parserObj.currentLine}`)
169
169
  }
170
170
 
171
171
  function rootHandler(elt) {
@@ -355,6 +355,7 @@ For methods which return a single **Twig** element (e.g. `elt.next("book")`) the
355
355
  `.namespace` - **object**: Namespace of the element or `null`. Only available if parsed with option `xmlns: true`.<br>
356
356
  Example `{ local: 'h', uri: 'http://www.w3.org/TR/html4/' }`
357
357
 
358
+ `.path` - **string**: The [XPath](https://www.w3.org/TR/xpath/) location of the Element. **Note:**<br> Like all other methods the returned path refers to currently loaded XML Chunk, not the input XML-File. Unlike JavaScript, indexes in XPath are starting at 1 instead of 0.
358
359
 
359
360
  #### Update XML Elements
360
361
 
package/doc/twig.md CHANGED
@@ -37,8 +37,8 @@
37
37
  <dt><a href="#onStart">onStart(binds, node, attrs)</a></dt>
38
38
  <dd><p>Common Event hanlder for starting tag</p>
39
39
  </dd>
40
- <dt><a href="#onClose">onClose(handler, options, name)</a></dt>
41
- <dd><p>Common Event hanlder for closing tag</p>
40
+ <dt><a href="#onClose">onClose(handler, parser, options, name)</a></dt>
41
+ <dd><p>Common Event hanlder for closing tag. On closed elements it either calls the Handler function or emits the specified event.</p>
42
42
  </dd>
43
43
  </dl>
44
44
 
@@ -1478,14 +1478,15 @@ Common Event hanlder for starting tag
1478
1478
 
1479
1479
  <a name="onClose"></a>
1480
1480
 
1481
- ## onClose(handler, options, name)
1482
- Common Event hanlder for closing tag
1481
+ ## onClose(handler, parser, options, name)
1482
+ Common Event hanlder for closing tag. On closed elements it either calls the Handler function or emits the specified event.
1483
1483
 
1484
1484
  **Kind**: global function
1485
1485
 
1486
1486
  | Param | Type | Description |
1487
1487
  | --- | --- | --- |
1488
1488
  | handler | [<code>TwigHandler</code>](#TwigHandler) \| [<code>Array.&lt;TwigHandler&gt;</code>](#TwigHandler) | Object or array of element specification and function to handle elements |
1489
+ | parser | [<code>sax</code>](https://www.npmjs.com/package/sax) \| [<code>node-expat</code>](https://www.npmjs.com/package/node-expat) | SAXStream or node-expat Stream object |
1489
1490
  | options | [<code>ParserOptions</code>](#ParserOptions) | Object of optional options |
1490
1491
  | name | <code>string</code> | Event handler parameter |
1491
1492
 
@@ -1505,6 +1506,7 @@ Optional settings for the Twig parser
1505
1506
  | [trim] | <code>boolean</code> | If `true`, then turn any whitespace into a single space. Text and comments are trimmed. |
1506
1507
  | [resumeAfterError] | <code>boolean</code> | If `true` then parser continues reading after an error. Otherwise it throws exception. |
1507
1508
  | [partial] | <code>boolean</code> | If `true` then unhandled elements are purged. |
1509
+ | [file] | <code>string</code> | The filename to be parsed. Just used for information and logging purpose. |
1508
1510
 
1509
1511
  **Example**
1510
1512
  ```js
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.4.1",
8
+ "version": "1.6.0",
9
9
  "main": "twig.js",
10
10
  "directories": {
11
11
  "doc": "doc"
package/twig.js CHANGED
@@ -63,6 +63,7 @@ const Any = new AnyHandler();
63
63
  * @property {boolean} [trim] - If `true`, then turn any whitespace into a single space. Text and comments are trimmed.
64
64
  * @property {boolean} [resumeAfterError] - If `true` then parser continues reading after an error. Otherwise it throws exception.
65
65
  * @property {boolean} [partial] - If `true` then unhandled elements are purged.
66
+ * @property {string} [file] - The filename to be parsed. Just used for information and logging purpose.
66
67
  * @example { method: 'expat', xmlns: true }
67
68
  * @default { method: 'sax', xmlns: false, trim: true, resumeAfterError: false, partial: false }
68
69
  */
@@ -158,7 +159,7 @@ function createParser(handler, options = {}) {
158
159
  get() { return parser._parser.column + 1; }
159
160
  });
160
161
 
161
- parser.on("closetag", onClose.bind(null, handler, options));
162
+ parser.on("closetag", onClose.bind(null, handler, parser, options));
162
163
  parser.on("opentagstart", onStart.bind(null, {
163
164
  handler: Array.isArray(handler) ? handler : [handler],
164
165
  options: options,
@@ -226,7 +227,7 @@ function createParser(handler, options = {}) {
226
227
  get() { return parser.parser.getCurrentColumnNumber(); }
227
228
  });
228
229
 
229
- parser.on("endElement", onClose.bind(null, handler, options));
230
+ parser.on("endElement", onClose.bind(null, handler, parser, options));
230
231
  parser.on("startElement", onStart.bind(null, {
231
232
  handler: Array.isArray(handler) ? handler : [handler],
232
233
  options: options,
@@ -266,6 +267,14 @@ function createParser(handler, options = {}) {
266
267
  enumerable: true
267
268
  });
268
269
 
270
+ if (options.file != null) {
271
+ Object.defineProperty(parser, 'file', {
272
+ value: options.file,
273
+ writable: false,
274
+ enumerable: true
275
+ });
276
+ }
277
+
269
278
  // Common events
270
279
  parser.on('text', function (str) {
271
280
  if (current === undefined || current === null) return;
@@ -370,38 +379,39 @@ function onStart(binds, node, attrs) {
370
379
  }
371
380
 
372
381
  /**
373
- * Common Event hanlder for closing tag
382
+ * Common Event hanlder for closing tag. On closed elements it either calls the Handler function or emits the specified event.
374
383
  * @param {TwigHandler|TwigHandler[]} handler - Object or array of element specification and function to handle elements
384
+ * @param {external:sax|external:node-expat} parser - SAXStream or node-expat Stream object
375
385
  * @param {ParserOptions} options - Object of optional options
376
386
  * @param {string} name - Event handler parameter
377
387
  */
378
- function onClose(handler, options, name) {
388
+ function onClose(handler, parser, options, name) {
379
389
  current.close();
380
390
  let purge = true;
381
391
 
382
392
  for (let hndl of Array.isArray(handler) ? handler : [handler]) {
383
393
  if (hndl.tag instanceof AnyHandler) {
384
- if (typeof hndl.function === 'function') hndl.function(current ?? tree);
394
+ if (typeof hndl.function === 'function') hndl.function(current ?? tree, parser);
385
395
  if (typeof hndl.event === 'string') parser.emit(hndl.event, current ?? tree);
386
396
  purge = false;
387
397
  } else if (hndl.tag instanceof RootHandler && current.isRoot) {
388
- if (typeof hndl.function === 'function') hndl.function(tree);
398
+ if (typeof hndl.function === 'function') hndl.function(tree, parser);
389
399
  if (typeof hndl.event === 'string') parser.emit(hndl.event, tree);
390
400
  purge = false;
391
401
  } else if (Array.isArray(hndl.tag) && hndl.tag.includes(name)) {
392
- if (typeof hndl.function === 'function') hndl.function(current ?? tree);
402
+ if (typeof hndl.function === 'function') hndl.function(current ?? tree, parser);
393
403
  if (typeof hndl.event === 'string') parser.emit(hndl.event, current ?? tree);
394
404
  purge = false;
395
405
  } else if (typeof hndl.tag === 'string' && name === hndl.tag) {
396
- if (typeof hndl.function === 'function') hndl.function(current ?? tree);
406
+ if (typeof hndl.function === 'function') hndl.function(current ?? tree, parser);
397
407
  if (typeof hndl.event === 'string') parser.emit(hndl.event, current ?? tree);
398
408
  purge = false;
399
409
  } else if (hndl.tag instanceof RegExp && hndl.tag.test(name)) {
400
- if (typeof hndl.function === 'function') hndl.function(current ?? tree);
410
+ if (typeof hndl.function === 'function') hndl.function(current ?? tree, parser);
401
411
  if (typeof hndl.event === 'string') parser.emit(hndl.event, current ?? tree);
402
412
  purge = false;
403
413
  } else if (typeof hndl.tag === 'function' && hndl.tag(name, current ?? tree)) {
404
- if (typeof hndl.function === 'function') hndl.function(current ?? tree);
414
+ if (typeof hndl.function === 'function') hndl.function(current ?? tree, parser);
405
415
  if (typeof hndl.event === 'string') parser.emit(hndl.event, current ?? tree);
406
416
  purge = false;
407
417
  }