xml-twig 1.2.88 → 1.2.91

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.
Files changed (4) hide show
  1. package/README.md +3 -3
  2. package/doc/twig.md +52 -101
  3. package/package.json +1 -1
  4. package/twig.js +33 -34
package/README.md CHANGED
@@ -217,7 +217,7 @@ The [Twig](./doc/twig.md#Twig) Class models a "some-kind" Element tree. I try t
217
217
  #### XML-Namespaces
218
218
 
219
219
  When the XML-Files uses [Namespaces](https://www.w3schools.com/xml/xml_namespaces.asp) then you can address the elements as they appear in the file, for example `cd:data`.
220
- With option `{ namespaces : true }` you will get access to the `.namespace` property.
220
+ With option `{ xmlns : true }` you will get access to the `.namespace` property.
221
221
 
222
222
  ### Access elements and attributes
223
223
 
@@ -232,7 +232,7 @@ With option `{ namespaces : true }` you will get access to the `.namespace` prop
232
232
  Specify attribute name or regular expression or custom condition. For details see [AttributeCondition](./doc/twig.md#AttributeCondition).<br>
233
233
  Let's assume an XML element like this:
234
234
  ```js
235
- <person firstName="Jean-Luc", lastName="Picard", age="59" />
235
+ <person firstName="Jean-Luc" lastName="Picard" age="59" />
236
236
  ```
237
237
  Here are some examples the get attribute and values:
238
238
  ```js
@@ -392,7 +392,7 @@ This `xml-twig` module focus on reading a XML files. In principle it would be po
392
392
 
393
393
  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.
394
394
 
395
-
395
+ Despite [W3C Recommendations](https://www.w3.org/TR/xml/#charencoding) ("All XML processors MUST be able to read entities in both the UTF-8 and UTF-16 encodings"), the `sax` parser does not support UTF-16 encodings. When you have a XML-File encoded in UF-16, then you must use the `expat` parser.
396
396
 
397
397
 
398
398
 
package/doc/twig.md CHANGED
@@ -112,12 +112,12 @@ You can specify a <code>function</code> or a <code>event</code> name</p>
112
112
  * [Twig](#Twig)
113
113
  * [new Twig()](#new_Twig_new)
114
114
  * [new Twig(name, [parent], [attributes], [index])](#new_Twig_new)
115
- * [.attributes](#Twig+attributes) ℗
116
- * [.text](#Twig+text) ℗
117
- * [.name](#Twig+name) ℗
118
- * [.children](#Twig+children) ℗
119
- * [.parent](#Twig+parent) ℗
120
- * [.pinned](#Twig+pinned) ℗
115
+ * [.attributes](#Twig+attributes) : <code>object</code>
116
+ * [.text](#Twig+text) : <code>string</code> \| <code>number</code>
117
+ * [.name](#Twig+name) : <code>string</code>
118
+ * [.children](#Twig+children) : [<code>Array.&lt;Twig&gt;</code>](#Twig)
119
+ * [.parent](#Twig+parent) : [<code>Twig</code>](#Twig) \| <code>undefined</code>
120
+ * [.pinned](#Twig+pinned) : <code>boolean</code>
121
121
  * [.purge](#Twig+purge)
122
122
  * [.purgeUpTo](#Twig+purgeUpTo)
123
123
  * [.escapeEntity](#Twig+escapeEntity)
@@ -187,70 +187,46 @@ Create a new Twig object
187
187
 
188
188
  <a name="Twig+attributes"></a>
189
189
 
190
- ### twig.attributes ℗
190
+ ### twig.attributes : <code>object</code>
191
+ XML attribute `{ <attribute 1>: <value 1>, <attribute 2>: <value 2>, ... }`
192
+
191
193
  **Kind**: instance property of [<code>Twig</code>](#Twig)
192
194
  **Access**: private
193
- **Properties**
194
-
195
- | Name | Type | Description |
196
- | --- | --- | --- |
197
- | #attributes | <code>object</code> | XML attribute `{ <attribute 1>: <value 1>, <attribute 2>: <value 2>, ... }` |
198
-
199
195
  <a name="Twig+text"></a>
200
196
 
201
- ### twig.text ℗
197
+ ### twig.text : <code>string</code> \| <code>number</code>
198
+ Content of XML Element
199
+
202
200
  **Kind**: instance property of [<code>Twig</code>](#Twig)
203
201
  **Access**: private
204
- **Properties**
205
-
206
- | Name | Type | Description |
207
- | --- | --- | --- |
208
- | #text | <code>string</code> \| <code>number</code> | Content of XML Element |
209
-
210
202
  <a name="Twig+name"></a>
211
203
 
212
- ### twig.name ℗
204
+ ### twig.name : <code>string</code>
205
+ The XML tag name
206
+
213
207
  **Kind**: instance property of [<code>Twig</code>](#Twig)
214
208
  **Access**: private
215
- **Properties**
216
-
217
- | Name | Type | Description |
218
- | --- | --- | --- |
219
- | #name | <code>string</code> | The XML tag name |
220
-
221
209
  <a name="Twig+children"></a>
222
210
 
223
- ### twig.children ℗
211
+ ### twig.children : [<code>Array.&lt;Twig&gt;</code>](#Twig)
212
+ Child XML Elements
213
+
224
214
  **Kind**: instance property of [<code>Twig</code>](#Twig)
225
215
  **Access**: private
226
- **Properties**
227
-
228
- | Name | Type | Description |
229
- | --- | --- | --- |
230
- | #children | [<code>Array.&lt;Twig&gt;</code>](#Twig) | Child XML Elements |
231
-
232
216
  <a name="Twig+parent"></a>
233
217
 
234
- ### twig.parent ℗
218
+ ### twig.parent : [<code>Twig</code>](#Twig) \| <code>undefined</code>
219
+ The parent object. Undefined on root element
220
+
235
221
  **Kind**: instance property of [<code>Twig</code>](#Twig)
236
222
  **Access**: private
237
- **Properties**
238
-
239
- | Name | Type | Description |
240
- | --- | --- | --- |
241
- | #parent | [<code>Twig</code>](#Twig) | The parent object. Undefined on root element |
242
-
243
223
  <a name="Twig+pinned"></a>
244
224
 
245
- ### twig.pinned ℗
225
+ ### twig.pinned : <code>boolean</code>
226
+ Determines whether twig is needed in partial load
227
+
246
228
  **Kind**: instance property of [<code>Twig</code>](#Twig)
247
229
  **Access**: private
248
- **Properties**
249
-
250
- | Name | Type | Description |
251
- | --- | --- | --- |
252
- | #pinned | <code>boolean</code> | Determines whether twig is needed in partial load |
253
-
254
230
  <a name="Twig+purge"></a>
255
231
 
256
232
  ### twig.purge
@@ -745,12 +721,12 @@ Common function to filter Twig element
745
721
  * [Twig](#Twig)
746
722
  * [new Twig()](#new_Twig_new)
747
723
  * [new Twig(name, [parent], [attributes], [index])](#new_Twig_new)
748
- * [.attributes](#Twig+attributes) ℗
749
- * [.text](#Twig+text) ℗
750
- * [.name](#Twig+name) ℗
751
- * [.children](#Twig+children) ℗
752
- * [.parent](#Twig+parent) ℗
753
- * [.pinned](#Twig+pinned) ℗
724
+ * [.attributes](#Twig+attributes) : <code>object</code>
725
+ * [.text](#Twig+text) : <code>string</code> \| <code>number</code>
726
+ * [.name](#Twig+name) : <code>string</code>
727
+ * [.children](#Twig+children) : [<code>Array.&lt;Twig&gt;</code>](#Twig)
728
+ * [.parent](#Twig+parent) : [<code>Twig</code>](#Twig) \| <code>undefined</code>
729
+ * [.pinned](#Twig+pinned) : <code>boolean</code>
754
730
  * [.purge](#Twig+purge)
755
731
  * [.purgeUpTo](#Twig+purgeUpTo)
756
732
  * [.escapeEntity](#Twig+escapeEntity)
@@ -820,70 +796,46 @@ Create a new Twig object
820
796
 
821
797
  <a name="Twig+attributes"></a>
822
798
 
823
- ### twig.attributes ℗
799
+ ### twig.attributes : <code>object</code>
800
+ XML attribute `{ <attribute 1>: <value 1>, <attribute 2>: <value 2>, ... }`
801
+
824
802
  **Kind**: instance property of [<code>Twig</code>](#Twig)
825
803
  **Access**: private
826
- **Properties**
827
-
828
- | Name | Type | Description |
829
- | --- | --- | --- |
830
- | #attributes | <code>object</code> | XML attribute `{ <attribute 1>: <value 1>, <attribute 2>: <value 2>, ... }` |
831
-
832
804
  <a name="Twig+text"></a>
833
805
 
834
- ### twig.text ℗
806
+ ### twig.text : <code>string</code> \| <code>number</code>
807
+ Content of XML Element
808
+
835
809
  **Kind**: instance property of [<code>Twig</code>](#Twig)
836
810
  **Access**: private
837
- **Properties**
838
-
839
- | Name | Type | Description |
840
- | --- | --- | --- |
841
- | #text | <code>string</code> \| <code>number</code> | Content of XML Element |
842
-
843
811
  <a name="Twig+name"></a>
844
812
 
845
- ### twig.name ℗
813
+ ### twig.name : <code>string</code>
814
+ The XML tag name
815
+
846
816
  **Kind**: instance property of [<code>Twig</code>](#Twig)
847
817
  **Access**: private
848
- **Properties**
849
-
850
- | Name | Type | Description |
851
- | --- | --- | --- |
852
- | #name | <code>string</code> | The XML tag name |
853
-
854
818
  <a name="Twig+children"></a>
855
819
 
856
- ### twig.children ℗
820
+ ### twig.children : [<code>Array.&lt;Twig&gt;</code>](#Twig)
821
+ Child XML Elements
822
+
857
823
  **Kind**: instance property of [<code>Twig</code>](#Twig)
858
824
  **Access**: private
859
- **Properties**
860
-
861
- | Name | Type | Description |
862
- | --- | --- | --- |
863
- | #children | [<code>Array.&lt;Twig&gt;</code>](#Twig) | Child XML Elements |
864
-
865
825
  <a name="Twig+parent"></a>
866
826
 
867
- ### twig.parent ℗
827
+ ### twig.parent : [<code>Twig</code>](#Twig) \| <code>undefined</code>
828
+ The parent object. Undefined on root element
829
+
868
830
  **Kind**: instance property of [<code>Twig</code>](#Twig)
869
831
  **Access**: private
870
- **Properties**
871
-
872
- | Name | Type | Description |
873
- | --- | --- | --- |
874
- | #parent | [<code>Twig</code>](#Twig) | The parent object. Undefined on root element |
875
-
876
832
  <a name="Twig+pinned"></a>
877
833
 
878
- ### twig.pinned ℗
834
+ ### twig.pinned : <code>boolean</code>
835
+ Determines whether twig is needed in partial load
836
+
879
837
  **Kind**: instance property of [<code>Twig</code>](#Twig)
880
838
  **Access**: private
881
- **Properties**
882
-
883
- | Name | Type | Description |
884
- | --- | --- | --- |
885
- | #pinned | <code>boolean</code> | Determines whether twig is needed in partial load |
886
-
887
839
  <a name="Twig+purge"></a>
888
840
 
889
841
  ### twig.purge
@@ -1463,21 +1415,20 @@ Create a new Twig parser
1463
1415
  Optional settings for the Twig parser
1464
1416
 
1465
1417
  **Kind**: global typedef
1466
- **Default**: <code>{ method: &#x27;sax&#x27;, encoding: &#x27;UTF-8&#x27;, xmlns: false, trim: true, resumeAfterError: false, partial: false }</code>
1418
+ **Default**: <code>{ method: &#x27;sax&#x27;, xmlns: false, trim: true, resumeAfterError: false, partial: false }</code>
1467
1419
  **Properties**
1468
1420
 
1469
1421
  | Name | Type | Description |
1470
1422
  | --- | --- | --- |
1471
- | [method] | <code>string</code> | The underlying parser. Either `'sax'` or `'expat'`. |
1472
- | [encoding] | <code>string</code> | Encoding of the XML File. Applies only to `expat` parser. |
1423
+ | [method] | <code>&#x27;sax&#x27;</code> \| <code>&#x27;expat&#x27;</code> | The underlying parser. Either `'sax'` or `'expat'`. |
1473
1424
  | [xmlns] | <code>boolean</code> | If `true`, then namespaces are accessible by `namespace` property. |
1474
1425
  | [trim] | <code>boolean</code> | If `true`, then turn any whitespace into a single space. Text and comments are trimmed. |
1475
1426
  | [resumeAfterError] | <code>boolean</code> | If `true` then parser continues reading after an error. Otherwise it throws exception. |
1476
- | [partial] | <code>boolean</code> | It `true` then unhandled elements are purged. |
1427
+ | [partial] | <code>boolean</code> | If `true` then unhandled elements are purged. |
1477
1428
 
1478
1429
  **Example**
1479
1430
  ```js
1480
- { encoding: 'UTF-8', xmlns: true }
1431
+ { method: 'expat', xmlns: true }
1481
1432
  ```
1482
1433
  <a name="TwigHandler"></a>
1483
1434
 
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.2.88",
8
+ "version": "1.2.91",
9
9
  "main": "twig.js",
10
10
  "directories": {
11
11
  "doc": "doc"
package/twig.js CHANGED
@@ -26,14 +26,13 @@ const Any = new AnyHandler();
26
26
  /**
27
27
  * Optional settings for the Twig parser
28
28
  * @typedef ParserOptions
29
- * @property {string} [method] - The underlying parser. Either `'sax'` or `'expat'`.
30
- * @property {string} [encoding] - Encoding of the XML File. Applies only to `expat` parser.
29
+ * @property {'sax' | 'expat'} [method] - The underlying parser. Either `'sax'` or `'expat'`.
31
30
  * @property {boolean} [xmlns] - If `true`, then namespaces are accessible by `namespace` property.
32
31
  * @property {boolean} [trim] - If `true`, then turn any whitespace into a single space. Text and comments are trimmed.
33
32
  * @property {boolean} [resumeAfterError] - If `true` then parser continues reading after an error. Otherwise it throws exception.
34
- * @property {boolean} [partial] - It `true` then unhandled elements are purged.
35
- * @example { encoding: 'UTF-8', xmlns: true }
36
- * @default { method: 'sax', encoding: 'UTF-8', xmlns: false, trim: true, resumeAfterError: false, partial: false }
33
+ * @property {boolean} [partial] - If `true` then unhandled elements are purged.
34
+ * @example { method: 'expat', xmlns: true }
35
+ * @default { method: 'sax', xmlns: false, trim: true, resumeAfterError: false, partial: false }
37
36
  */
38
37
 
39
38
  /**
@@ -96,15 +95,15 @@ const Any = new AnyHandler();
96
95
  * @param {ParserOptions} [options] - Object of optional options
97
96
  * @throws {UnsupportedParser} - For an unsupported parser. Currently `expat` and `sax` (default) are supported.
98
97
  */
99
- function createParser(handler, options) {
100
- options = Object.assign({ method: SAX, encoding: 'UTF-8', xmlns: false, trim: true, resumeAfterError: false, partial: false }, options);
98
+ function createParser(handler, options = {}) {
99
+ options = Object.assign({ method: SAX, xmlns: false, trim: true, resumeAfterError: false, partial: false }, options);
101
100
  let parser;
102
101
  let namespaces = {};
103
102
  let closeEvent;
104
103
 
105
104
  if (options.partial) {
106
- let hndl = Array.isArray(handler) ? handler : [handler];
107
- let any = hndl.find(x => x.tag instanceof AnyHandler);
105
+ const handle1 = Array.isArray(handler) ? handler : [handler];
106
+ let any = handle1.find(x => x.tag instanceof AnyHandler);
108
107
  if (any !== undefined)
109
108
  console.warn(`Using option '{ partial: true }' and handler '{ tag: Any, function: ${any.function.toString()} }' does not make much sense`);
110
109
  }
@@ -187,7 +186,7 @@ function createParser(handler, options) {
187
186
 
188
187
  parser.on("attribute", function (attr) {
189
188
  current.attribute(attr.name, attr.value);
190
- if (attr.uri !== undefined && attr.uri !== '') {
189
+ if ((attr.uri ?? '') !== '' && attr.local !== undefined) {
191
190
  namespaces[attr.local] = attr.uri;
192
191
  Object.defineProperty(current, 'namespace', {
193
192
  value: { local: attr.local, uri: attr.uri },
@@ -200,7 +199,7 @@ function createParser(handler, options) {
200
199
  current.text = current.text ?? '' + str;
201
200
  });
202
201
 
203
- let hndl = Array.isArray(handler) ? handler : [handler];
202
+ const hndl = Array.isArray(handler) ? handler : [handler];
204
203
  let rootHandler = hndl.find(x => x.tag instanceof RootHandler);
205
204
  parser.on("end", function () {
206
205
  if (typeof rootHandler?.function === 'function') rootHandler.function(tree);
@@ -209,8 +208,6 @@ function createParser(handler, options) {
209
208
 
210
209
  } else if (options.method === EXPAT) {
211
210
  parser = require("node-expat").createParser();
212
- parser.encoding = options.encoding;
213
-
214
211
  Object.defineProperty(parser, 'currentLine', {
215
212
  enumerable: true,
216
213
  get() { return parser.parser.getCurrentLineNumber(); }
@@ -245,6 +242,8 @@ function createParser(handler, options) {
245
242
  }
246
243
  }
247
244
  }
245
+ for (let attr in attrs)
246
+ current.attribute(attr, attrs[attr]);
248
247
  if (options.xmlns) {
249
248
  for (let key of Object.keys(attrs).filter(x => x.startsWith('xmlns:')))
250
249
  namespaces[key.split(':')[1]] = attrs[key];
@@ -391,38 +390,38 @@ class Twig {
391
390
  */
392
391
 
393
392
  /**
394
- * @property {?object} #attributes - XML attribute `{ <attribute 1>: <value 1>, <attribute 2>: <value 2>, ... }`
395
- * @private
393
+ * XML attribute `{ <attribute 1>: <value 1>, <attribute 2>: <value 2>, ... }`
394
+ * @type {?object}
396
395
  */
397
396
  #attributes = {};
398
397
 
399
398
  /**
400
- * @property {?string|number} #text - Content of XML Element
401
- * @private
399
+ * Content of XML Element
400
+ * @type {?string|number}
402
401
  */
403
402
  #text = null;
404
403
 
405
404
  /**
406
- * @property {string} #name - The XML tag name
407
- * @private
405
+ * The XML tag name
406
+ * @type {string}
408
407
  */
409
408
  #name;
410
409
 
411
410
  /**
412
- * @property {?Twig[]} #children - Child XML Elements
413
- * @private
411
+ * Child XML Elements
412
+ * @type {Twig[]}
414
413
  */
415
414
  #children = [];
416
415
 
417
416
  /**
418
- * @property {?Twig} #parent - The parent object. Undefined on root element
419
- * @private
417
+ * The parent object. Undefined on root element
418
+ * @type {Twig | undefined}
420
419
  */
421
420
  #parent;
422
421
 
423
422
  /**
424
- * @property {boolean} #pinned - Determines whether twig is needed in partial load
425
- * @private
423
+ * Determines whether twig is needed in partial load
424
+ * @type {boolean}
426
425
  */
427
426
  #pinned = false;
428
427
 
@@ -482,14 +481,14 @@ class Twig {
482
481
  if (elt === undefined) {
483
482
  this.purge();
484
483
  } else {
485
- let purgeThis = this.descendantOrSelf();
486
- purgeThis = purgeThis[purgeThis.length - 1];
487
- let stopAt = elt.descendantOrSelf();
488
- stopAt = stopAt[stopAt.length - 1];
489
- while (purgeThis !== null && !Object.is(purgeThis, stopAt)) {
490
- let prev = purgeThis.previous();
491
- purgeThis.purge();
492
- purgeThis = prev;
484
+ const purgeThis = this.descendantOrSelf();
485
+ let toPurge = purgeThis[purgeThis.length - 1];
486
+ const descendantOrSelf = elt.descendantOrSelf();
487
+ const stopAt = descendantOrSelf[descendantOrSelf.length - 1];
488
+ while (toPurge !== null && !Object.is(toPurge, stopAt)) {
489
+ const prev = toPurge.previous();
490
+ toPurge.purge();
491
+ toPurge = prev;
493
492
  }
494
493
  }
495
494
  };
@@ -784,7 +783,7 @@ class Twig {
784
783
  if (typeof condition === 'string') {
785
784
  return elements.filter(x => x.name === condition);
786
785
  } else if (condition instanceof RegExp) {
787
- return elements.filter(x => x.condition.test(x.name));
786
+ return elements.filter(x => condition.test(x.name));
788
787
  } else if (condition instanceof Twig) {
789
788
  return elements.filter(x => Object.is(x, condition));
790
789
  } else if (typeof condition === 'function') {