xml-twig 1.1.3 → 1.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 +45 -27
- package/demo.js +12 -0
- package/doc/build.sh +6 -6
- package/doc/twig.md +145 -72
- package/package.json +1 -2
- package/samples/sample.js +8 -0
- package/twig.js +95 -41
package/README.md
CHANGED
|
@@ -37,18 +37,6 @@ In my tests I parsed a 750 MB big XML file, the `node-expat` is around two times
|
|
|
37
37
|
|
|
38
38
|
## How to use it
|
|
39
39
|
|
|
40
|
-
#### Names and Definitions
|
|
41
|
-
|
|
42
|
-
In XML-Path, there are seven kinds of nodes: `element`, `attribute`, `text`, `namespace`, `processingInstruction`, `comment`, and `document`, see [Nodes at W3C](https://www.w3.org/TR/xpath-datamodel-31/#Node). XML documents are treated as trees of nodes.
|
|
43
|
-
|
|
44
|
-
The [Twig](./doc/twig.md#Twig) Class models a "some-kind" Element tree. I try to follow the [XML-Path](https://www.w3.org/TR/xpath/) conventions whenever possible to avoid confusion.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
#### XML-Namespaces
|
|
48
|
-
|
|
49
|
-
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`.
|
|
50
|
-
With option `{ namespaces : true }` you will get access to the `.namespace` property.
|
|
51
|
-
|
|
52
40
|
### Read XML Document
|
|
53
41
|
|
|
54
42
|
- **Read entire XML file at once**
|
|
@@ -90,7 +78,9 @@ With option `{ namespaces : true }` you will get access to the `.namespace` prop
|
|
|
90
78
|
|
|
91
79
|
- **Read XML Document in chucks**
|
|
92
80
|
|
|
93
|
-
The key feature of this module is to read and process XML files in chunks. You need to create handler functions for elements you like to process
|
|
81
|
+
The key feature of this module is to read and process XML files in chunks. You need to create handler functions for elements you like to process.<br>
|
|
82
|
+
The most notable difference to other parsers is the `purge()` and `purgeUpTo()` method. The parser reads the element and you decide how long you need to keep it in the memory.
|
|
83
|
+
In many cases you will purge it immediately after you have used it but in some cases you may keep the element for later use. The parser knows the element position in the XML-Tree.
|
|
94
84
|
|
|
95
85
|
|
|
96
86
|
```
|
|
@@ -215,6 +205,18 @@ Be aware if you run methods like `elt.followingSibling()`, `elt.descendant()`, `
|
|
|
215
205
|
For details and other options, see [ParserOptions](./doc/twig.md#ParserOptions) and [TwigHandler](./doc/twig.md#TwigHandler)
|
|
216
206
|
|
|
217
207
|
|
|
208
|
+
#### Names and Definitions
|
|
209
|
+
|
|
210
|
+
In XML-Path, there are seven kinds of nodes: `element`, `attribute`, `text`, `namespace`, `processingInstruction`, `comment`, and `document`, see [Nodes at W3C](https://www.w3.org/TR/xpath-datamodel-31/#Node). XML documents are treated as trees of nodes.
|
|
211
|
+
|
|
212
|
+
The [Twig](./doc/twig.md#Twig) Class models a "some-kind" Element tree. I try to follow the [XML-Path](https://www.w3.org/TR/xpath/) conventions whenever possible to avoid confusion.
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
#### XML-Namespaces
|
|
216
|
+
|
|
217
|
+
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`.
|
|
218
|
+
With option `{ namespaces : true }` you will get access to the `.namespace` property.
|
|
219
|
+
|
|
218
220
|
### Access elements and attributes
|
|
219
221
|
|
|
220
222
|
#### Get XML Attributes
|
|
@@ -301,20 +303,16 @@ You can specify condition on above methods. You can filter elements by following
|
|
|
301
303
|
|
|
302
304
|
- If `undefined`, then all elements are returned.
|
|
303
305
|
|
|
304
|
-
- If `string` then the element name must be equal to the string
|
|
305
|
-
|
|
306
|
+
- If `string` then the element name must be equal to the string<br>
|
|
306
307
|
Example: `"book"`
|
|
307
308
|
|
|
308
|
-
- If `RegExp` then the element name must match the Regular Expression
|
|
309
|
-
|
|
309
|
+
- If `RegExp` then the element name must match the Regular Expression<br>
|
|
310
310
|
Example: `/book$/i`
|
|
311
311
|
|
|
312
312
|
- With `ElementConditionFilter` you can specify any custom filter function.<br>
|
|
313
|
-
|
|
314
313
|
Example: `(name, elt) => { return name === 'book' && elt.children().length > 1 }`
|
|
315
314
|
|
|
316
|
-
- With a `Twig` object, you can specify the element directly. Apart from `purgeUpTo(elt)`, it is rarely used, because when you know the element then there is no reason to find it again
|
|
317
|
-
|
|
315
|
+
- With a `Twig` object, you can specify the element directly. Apart from `purgeUpTo(elt)`, it is rarely used, because when you know the element then there is no reason to find it again.<br>
|
|
318
316
|
Example: `elt.children()[2]`
|
|
319
317
|
|
|
320
318
|
|
|
@@ -339,7 +337,7 @@ For methods which return a single **Twig** element (e.g. `elt.next("book")`) the
|
|
|
339
337
|
|
|
340
338
|
`.isLastChild` - **boolean**: `true` if the element is the last child in the parent
|
|
341
339
|
|
|
342
|
-
`.index` - **integer**: The
|
|
340
|
+
`.index` - **integer**: The position (starting at 0) of the element within the parent. The root element returns always 0
|
|
343
341
|
|
|
344
342
|
`.name` - **string**: Name of the element/tag
|
|
345
343
|
|
|
@@ -351,19 +349,39 @@ For methods which return a single **Twig** element (e.g. `elt.next("book")`) the
|
|
|
351
349
|
|
|
352
350
|
`.comment` - **string|string[]**: Comments or array of comments inside the element
|
|
353
351
|
|
|
354
|
-
`.declaration` - **object**: The XML-Declaration object, exist only on `root
|
|
355
|
-
|
|
352
|
+
`.declaration` - **object**: The XML-Declaration object, exist only on `root`.<br>
|
|
356
353
|
Example `{version: '1.0', encoding: 'UTF-8'}`.
|
|
357
354
|
|
|
358
|
-
`.PI` - **object**: Processing Instruction, exist only on `root
|
|
359
|
-
|
|
355
|
+
`.PI` - **object**: Processing Instruction, exist only on `root`.<br>
|
|
360
356
|
Example `{ target: 'xml-stylesheet', data: 'type="text/xsl" href="style.xsl"' }`.
|
|
361
357
|
|
|
362
|
-
`.namespace` - **object**: Namespace of the element or `null`. Only available if parsed with option `xmlns: true
|
|
363
|
-
|
|
358
|
+
`.namespace` - **object**: Namespace of the element or `null`. Only available if parsed with option `xmlns: true`.<br>
|
|
364
359
|
Example `{ local: 'h', uri: 'http://www.w3.org/TR/html4/' }`
|
|
365
360
|
|
|
366
361
|
|
|
362
|
+
#### Update XML Elements
|
|
363
|
+
|
|
364
|
+
To update the XML, use these methods. These methods modify the XML tree in the memory, not the input XML file. Use `writer()` to print modified XML or save it to a file.
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
`.attribute(name, value)`: Updates an attribute.<br>
|
|
368
|
+
`name`: Name of the attribute. Regular Expression or other conditions are not supported<br>
|
|
369
|
+
`value`: Then new value
|
|
370
|
+
|
|
371
|
+
`.deleteAttribute(name)`: Deletes the attribute.<br>
|
|
372
|
+
`name`: Name of the attribute. Regular Expression or other conditions are not supported
|
|
373
|
+
|
|
374
|
+
`.text(value)`: Update the text (PCDATA) of current element<br>
|
|
375
|
+
`value`: The new text or `null` to remove any text
|
|
376
|
+
|
|
377
|
+
`.addElement(name, text, attributes, position)`: Adds a new child element to the current element<br>
|
|
378
|
+
`name`: The name/tag of the new element<br>
|
|
379
|
+
`text`: The text (PCDATA) of the element or `null`<br>
|
|
380
|
+
`attributes`: Object of XML attributes, example: `{ id: 1, lang="en" }` or `null`<br>
|
|
381
|
+
`position`: The position in `children()` array where you like to add new child. You can also specify `'first'` or `'last'`
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
367
385
|
## Limitations
|
|
368
386
|
|
|
369
387
|
This `xml-twig` module focus on reading a XML files. In principle it would be possible to create a XML file from scratch with the [Twig](./doc/twig.md#Twig) class. However, I think there are better modules available. Of course, you may run operations like `elt.root().children().push(elt.root().children()[0])`, but I think this is not so handy to use.
|
package/demo.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const twig = require('./twig.js');
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const parser = twig.createParser({ tag: 'book', event: 'bookElement' });
|
|
6
|
+
fs.createReadStream(`${__dirname}/samples/bookstore.xml`).pipe(parser);
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
parser.on('bookElement', (elt) => {
|
|
10
|
+
console.log(`<${elt.name}> finished after ${parser.currentLine} lines`);
|
|
11
|
+
})
|
|
12
|
+
|
package/doc/build.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
jsdoc2md --private ../twig.js > ./twig.md
|
|
4
|
-
|
|
5
|
-
# see https://github.com/jsdoc2md/jsdoc-to-markdown
|
|
6
|
-
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
jsdoc2md --private ../twig.js > ./twig.md
|
|
4
|
+
|
|
5
|
+
# see https://github.com/jsdoc2md/jsdoc-to-markdown
|
|
6
|
+
|
package/doc/twig.md
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
<dd></dd>
|
|
6
6
|
<dt><a href="#Twig">Twig</a></dt>
|
|
7
7
|
<dd></dd>
|
|
8
|
+
<dt><a href="#NotImplementedYet">NotImplementedYet</a></dt>
|
|
9
|
+
<dd><p>Generic error for non implemented feature</p>
|
|
10
|
+
</dd>
|
|
8
11
|
<dt><a href="#UnsupportedParser">UnsupportedParser</a></dt>
|
|
9
12
|
<dd><p>Error for unsupported data types</p>
|
|
10
13
|
</dd>
|
|
@@ -108,13 +111,16 @@ You can specify a <code>function</code> or a <code>event</code> name</p>
|
|
|
108
111
|
|
|
109
112
|
* [Twig](#Twig)
|
|
110
113
|
* [new Twig()](#new_Twig_new)
|
|
111
|
-
* [new Twig(name, parent, attributes)](#new_Twig_new)
|
|
114
|
+
* [new Twig(name, parent, attributes, index)](#new_Twig_new)
|
|
112
115
|
* [.attributes](#Twig+attributes) ℗
|
|
113
116
|
* [.text](#Twig+text) ℗
|
|
114
117
|
* [.name](#Twig+name) ℗
|
|
115
118
|
* [.children](#Twig+children) ℗
|
|
116
119
|
* [.parent](#Twig+parent) ℗
|
|
117
120
|
* [.pinned](#Twig+pinned) ℗
|
|
121
|
+
* [.purge](#Twig+purge)
|
|
122
|
+
* [.purgeUpTo](#Twig+purgeUpTo)
|
|
123
|
+
* [.escapeEntity](#Twig+escapeEntity)
|
|
118
124
|
* [.isEmpty](#Twig+isEmpty) ⇒ <code>boolean</code>
|
|
119
125
|
* [.level](#Twig+level) ⇒ <code>number</code>
|
|
120
126
|
* [.isRoot](#Twig+isRoot) ⇒ <code>boolean</code>
|
|
@@ -126,7 +132,6 @@ You can specify a <code>function</code> or a <code>event</code> name</p>
|
|
|
126
132
|
* [.text](#Twig+text)
|
|
127
133
|
* [.pin](#Twig+pin)
|
|
128
134
|
* [.pinned](#Twig+pinned) ⇒ <code>boolean</code>
|
|
129
|
-
* [.text](#Twig+text)
|
|
130
135
|
* [.close](#Twig+close)
|
|
131
136
|
* [.addChild](#Twig+addChild) ℗
|
|
132
137
|
* [.writer](#Twig+writer) ⇒ <code>XMLWriter</code>
|
|
@@ -134,6 +139,7 @@ You can specify a <code>function</code> or a <code>event</code> name</p>
|
|
|
134
139
|
* [.attributes](#Twig+attributes) ⇒ <code>object</code>
|
|
135
140
|
* [.hasAttribute](#Twig+hasAttribute) ⇒ <code>boolean</code>
|
|
136
141
|
* [.attribute](#Twig+attribute) ⇒ <code>object</code>
|
|
142
|
+
* [.deleteAttribute](#Twig+deleteAttribute)
|
|
137
143
|
* [.root](#Twig+root) ⇒ [<code>Twig</code>](#Twig)
|
|
138
144
|
* [.parent](#Twig+parent) ⇒ [<code>Twig</code>](#Twig)
|
|
139
145
|
* [.self](#Twig+self) ⇒ [<code>Twig</code>](#Twig)
|
|
@@ -155,8 +161,8 @@ You can specify a <code>function</code> or a <code>event</code> name</p>
|
|
|
155
161
|
* [.nextSibling](#Twig+nextSibling) ⇒ [<code>Twig</code>](#Twig)
|
|
156
162
|
* [.prevSibling](#Twig+prevSibling) ⇒ [<code>Twig</code>](#Twig)
|
|
157
163
|
* [.find](#Twig+find) ⇒ [<code>Twig</code>](#Twig)
|
|
158
|
-
* [.
|
|
159
|
-
* [.
|
|
164
|
+
* [.addElement](#Twig+addElement) ⇒ [<code>Twig</code>](#Twig)
|
|
165
|
+
* [.delete](#Twig+delete)
|
|
160
166
|
* [.setRoot(name)](#Twig+setRoot) ℗
|
|
161
167
|
* [.filterElements(elements, condition)](#Twig+filterElements) ⇒ [<code>Array.<Twig></code>](#Twig)
|
|
162
168
|
* [.testElement(element, condition)](#Twig+testElement) ⇒ <code>boolean</code>
|
|
@@ -168,7 +174,7 @@ Generic class modeling a XML Node
|
|
|
168
174
|
|
|
169
175
|
<a name="new_Twig_new"></a>
|
|
170
176
|
|
|
171
|
-
### new Twig(name, parent, attributes)
|
|
177
|
+
### new Twig(name, parent, attributes, index)
|
|
172
178
|
Create a new Twig object
|
|
173
179
|
|
|
174
180
|
|
|
@@ -177,6 +183,7 @@ Create a new Twig object
|
|
|
177
183
|
| name | <code>string</code> | The name of the XML element |
|
|
178
184
|
| parent | [<code>Twig</code>](#Twig) | The parent object |
|
|
179
185
|
| attributes | <code>object</code> | Attribute object |
|
|
186
|
+
| index | <code>string</code> \| <code>number</code> | Position name 'first', 'last' or the position in the current `children` array.<br>Defaults to 'last' |
|
|
180
187
|
|
|
181
188
|
<a name="Twig+attributes"></a>
|
|
182
189
|
|
|
@@ -244,6 +251,34 @@ Create a new Twig object
|
|
|
244
251
|
| --- | --- | --- |
|
|
245
252
|
| #pinned | <code>boolean</code> | Determines whether twig is needed in partial load |
|
|
246
253
|
|
|
254
|
+
<a name="Twig+purge"></a>
|
|
255
|
+
|
|
256
|
+
### twig.purge
|
|
257
|
+
Purges the current, typically used after element has been processed.<br>The root object cannot be purged.
|
|
258
|
+
|
|
259
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
260
|
+
<a name="Twig+purgeUpTo"></a>
|
|
261
|
+
|
|
262
|
+
### twig.purgeUpTo
|
|
263
|
+
Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.
|
|
264
|
+
|
|
265
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
266
|
+
|
|
267
|
+
| Param | Type | Description |
|
|
268
|
+
| --- | --- | --- |
|
|
269
|
+
| elt | [<code>Twig</code>](#Twig) | Up to this element the tree will be purged. The `elt` object itself is not purged.<br> If `undefined` then the current element is purged (i.e. `purge()`) |
|
|
270
|
+
|
|
271
|
+
<a name="Twig+escapeEntity"></a>
|
|
272
|
+
|
|
273
|
+
### twig.escapeEntity
|
|
274
|
+
Escapes special XML characters. According W3C specification these are only `&, <, >, ", '` - this is a XML parser, not HTML!
|
|
275
|
+
|
|
276
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
277
|
+
|
|
278
|
+
| Param | Type | Description |
|
|
279
|
+
| --- | --- | --- |
|
|
280
|
+
| text | <code>string</code> | Input text to be escaped |
|
|
281
|
+
|
|
247
282
|
<a name="Twig+isEmpty"></a>
|
|
248
283
|
|
|
249
284
|
### twig.isEmpty ⇒ <code>boolean</code>
|
|
@@ -303,17 +338,17 @@ The text of the element. No matter if given as text or CDATA entity
|
|
|
303
338
|
<a name="Twig+text"></a>
|
|
304
339
|
|
|
305
340
|
### twig.text
|
|
306
|
-
|
|
341
|
+
Update the text of the element
|
|
307
342
|
|
|
308
343
|
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
309
344
|
**Throws**:
|
|
310
345
|
|
|
311
|
-
- [<code>UnsupportedType</code>](#UnsupportedType) - If value is not a string or numeric type
|
|
346
|
+
- [<code>UnsupportedType</code>](#UnsupportedType) - If value is not a string, boolean or numeric type
|
|
312
347
|
|
|
313
348
|
|
|
314
349
|
| Param | Type | Description |
|
|
315
350
|
| --- | --- | --- |
|
|
316
|
-
| value | <code>string</code> | New
|
|
351
|
+
| value | <code>string</code> \| <code>number</code> \| <code>bigint</code> \| <code>boolean</code> | New text of the element |
|
|
317
352
|
|
|
318
353
|
<a name="Twig+pin"></a>
|
|
319
354
|
|
|
@@ -328,21 +363,6 @@ Checks if element is pinned
|
|
|
328
363
|
|
|
329
364
|
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
330
365
|
**Returns**: <code>boolean</code> - `true` when the element is pinned
|
|
331
|
-
<a name="Twig+text"></a>
|
|
332
|
-
|
|
333
|
-
### twig.text
|
|
334
|
-
Modifies the text of the element
|
|
335
|
-
|
|
336
|
-
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
337
|
-
**Throws**:
|
|
338
|
-
|
|
339
|
-
- [<code>UnsupportedType</code>](#UnsupportedType) - If value is not a string or numeric type
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
| Param | Type | Description |
|
|
343
|
-
| --- | --- | --- |
|
|
344
|
-
| value | <code>string</code> | New value of the attribute |
|
|
345
|
-
|
|
346
366
|
<a name="Twig+close"></a>
|
|
347
367
|
|
|
348
368
|
### twig.close
|
|
@@ -407,7 +427,7 @@ Check if the attribute exist or not
|
|
|
407
427
|
<a name="Twig+attribute"></a>
|
|
408
428
|
|
|
409
429
|
### twig.attribute ⇒ <code>object</code>
|
|
410
|
-
Retrieve or update XML attribute.
|
|
430
|
+
Retrieve or update XML attribute. For update, the condition must be a string, i.e. must match to one attribute only.
|
|
411
431
|
|
|
412
432
|
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
413
433
|
**Returns**: <code>object</code> - Attributes or `null` if no matching attribute found
|
|
@@ -415,12 +435,23 @@ Retrieve or update XML attribute.
|
|
|
415
435
|
| Param | Type | Description |
|
|
416
436
|
| --- | --- | --- |
|
|
417
437
|
| condition | [<code>AttributeCondition</code>](#AttributeCondition) | Optional condition to select attributes |
|
|
418
|
-
|
|
|
438
|
+
| value | <code>string</code> \| <code>number</code> \| <code>bigint</code> \| <code>boolean</code> | New value of the attribute.<br>If `undefined` then existing attributes is returned. |
|
|
419
439
|
|
|
420
440
|
**Example**
|
|
421
441
|
```js
|
|
422
442
|
attribute((name, val) => { return name === 'age' && val > 50})
|
|
423
443
|
```
|
|
444
|
+
<a name="Twig+deleteAttribute"></a>
|
|
445
|
+
|
|
446
|
+
### twig.deleteAttribute
|
|
447
|
+
Delete the attribute
|
|
448
|
+
|
|
449
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
450
|
+
|
|
451
|
+
| Param | Type | Description |
|
|
452
|
+
| --- | --- | --- |
|
|
453
|
+
| name | <code>string</code> | The attribute name |
|
|
454
|
+
|
|
424
455
|
<a name="Twig+root"></a>
|
|
425
456
|
|
|
426
457
|
### twig.root ⇒ [<code>Twig</code>](#Twig)
|
|
@@ -647,23 +678,27 @@ Find a specific element within current element. Same as `.descendant(condition)[
|
|
|
647
678
|
| --- | --- | --- |
|
|
648
679
|
| condition | [<code>ElementCondition</code>](#ElementCondition) | Find condition |
|
|
649
680
|
|
|
650
|
-
<a name="Twig+
|
|
651
|
-
|
|
652
|
-
### twig.purge()
|
|
653
|
-
Purges the current, typically used after element has been processed.<br>The root object cannot be purged.
|
|
681
|
+
<a name="Twig+addElement"></a>
|
|
654
682
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
### twig.purgeUpTo(elt)
|
|
659
|
-
Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.
|
|
683
|
+
### twig.addElement ⇒ [<code>Twig</code>](#Twig)
|
|
684
|
+
Add a new element in the current element
|
|
660
685
|
|
|
661
|
-
**Kind**: instance
|
|
686
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
687
|
+
**Returns**: [<code>Twig</code>](#Twig) - - The appended element
|
|
662
688
|
|
|
663
689
|
| Param | Type | Description |
|
|
664
690
|
| --- | --- | --- |
|
|
665
|
-
|
|
|
691
|
+
| name | <code>string</code> | The tag name |
|
|
692
|
+
| text | <code>string</code> | Text of the element |
|
|
693
|
+
| attributes | <code>object</code> | Element attributes |
|
|
694
|
+
| position | <code>name</code> \| <code>number</code> | Position name 'first', 'last' or the position in the `children` |
|
|
695
|
+
|
|
696
|
+
<a name="Twig+delete"></a>
|
|
666
697
|
|
|
698
|
+
### twig.delete
|
|
699
|
+
Deletes the current element from tree, same as `purge()`. The root object cannot be deleted.
|
|
700
|
+
|
|
701
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
667
702
|
<a name="Twig+setRoot"></a>
|
|
668
703
|
|
|
669
704
|
### twig.setRoot(name) ℗
|
|
@@ -709,13 +744,16 @@ Common function to filter Twig element
|
|
|
709
744
|
|
|
710
745
|
* [Twig](#Twig)
|
|
711
746
|
* [new Twig()](#new_Twig_new)
|
|
712
|
-
* [new Twig(name, parent, attributes)](#new_Twig_new)
|
|
747
|
+
* [new Twig(name, parent, attributes, index)](#new_Twig_new)
|
|
713
748
|
* [.attributes](#Twig+attributes) ℗
|
|
714
749
|
* [.text](#Twig+text) ℗
|
|
715
750
|
* [.name](#Twig+name) ℗
|
|
716
751
|
* [.children](#Twig+children) ℗
|
|
717
752
|
* [.parent](#Twig+parent) ℗
|
|
718
753
|
* [.pinned](#Twig+pinned) ℗
|
|
754
|
+
* [.purge](#Twig+purge)
|
|
755
|
+
* [.purgeUpTo](#Twig+purgeUpTo)
|
|
756
|
+
* [.escapeEntity](#Twig+escapeEntity)
|
|
719
757
|
* [.isEmpty](#Twig+isEmpty) ⇒ <code>boolean</code>
|
|
720
758
|
* [.level](#Twig+level) ⇒ <code>number</code>
|
|
721
759
|
* [.isRoot](#Twig+isRoot) ⇒ <code>boolean</code>
|
|
@@ -727,7 +765,6 @@ Common function to filter Twig element
|
|
|
727
765
|
* [.text](#Twig+text)
|
|
728
766
|
* [.pin](#Twig+pin)
|
|
729
767
|
* [.pinned](#Twig+pinned) ⇒ <code>boolean</code>
|
|
730
|
-
* [.text](#Twig+text)
|
|
731
768
|
* [.close](#Twig+close)
|
|
732
769
|
* [.addChild](#Twig+addChild) ℗
|
|
733
770
|
* [.writer](#Twig+writer) ⇒ <code>XMLWriter</code>
|
|
@@ -735,6 +772,7 @@ Common function to filter Twig element
|
|
|
735
772
|
* [.attributes](#Twig+attributes) ⇒ <code>object</code>
|
|
736
773
|
* [.hasAttribute](#Twig+hasAttribute) ⇒ <code>boolean</code>
|
|
737
774
|
* [.attribute](#Twig+attribute) ⇒ <code>object</code>
|
|
775
|
+
* [.deleteAttribute](#Twig+deleteAttribute)
|
|
738
776
|
* [.root](#Twig+root) ⇒ [<code>Twig</code>](#Twig)
|
|
739
777
|
* [.parent](#Twig+parent) ⇒ [<code>Twig</code>](#Twig)
|
|
740
778
|
* [.self](#Twig+self) ⇒ [<code>Twig</code>](#Twig)
|
|
@@ -756,8 +794,8 @@ Common function to filter Twig element
|
|
|
756
794
|
* [.nextSibling](#Twig+nextSibling) ⇒ [<code>Twig</code>](#Twig)
|
|
757
795
|
* [.prevSibling](#Twig+prevSibling) ⇒ [<code>Twig</code>](#Twig)
|
|
758
796
|
* [.find](#Twig+find) ⇒ [<code>Twig</code>](#Twig)
|
|
759
|
-
* [.
|
|
760
|
-
* [.
|
|
797
|
+
* [.addElement](#Twig+addElement) ⇒ [<code>Twig</code>](#Twig)
|
|
798
|
+
* [.delete](#Twig+delete)
|
|
761
799
|
* [.setRoot(name)](#Twig+setRoot) ℗
|
|
762
800
|
* [.filterElements(elements, condition)](#Twig+filterElements) ⇒ [<code>Array.<Twig></code>](#Twig)
|
|
763
801
|
* [.testElement(element, condition)](#Twig+testElement) ⇒ <code>boolean</code>
|
|
@@ -769,7 +807,7 @@ Generic class modeling a XML Node
|
|
|
769
807
|
|
|
770
808
|
<a name="new_Twig_new"></a>
|
|
771
809
|
|
|
772
|
-
### new Twig(name, parent, attributes)
|
|
810
|
+
### new Twig(name, parent, attributes, index)
|
|
773
811
|
Create a new Twig object
|
|
774
812
|
|
|
775
813
|
|
|
@@ -778,6 +816,7 @@ Create a new Twig object
|
|
|
778
816
|
| name | <code>string</code> | The name of the XML element |
|
|
779
817
|
| parent | [<code>Twig</code>](#Twig) | The parent object |
|
|
780
818
|
| attributes | <code>object</code> | Attribute object |
|
|
819
|
+
| index | <code>string</code> \| <code>number</code> | Position name 'first', 'last' or the position in the current `children` array.<br>Defaults to 'last' |
|
|
781
820
|
|
|
782
821
|
<a name="Twig+attributes"></a>
|
|
783
822
|
|
|
@@ -845,6 +884,34 @@ Create a new Twig object
|
|
|
845
884
|
| --- | --- | --- |
|
|
846
885
|
| #pinned | <code>boolean</code> | Determines whether twig is needed in partial load |
|
|
847
886
|
|
|
887
|
+
<a name="Twig+purge"></a>
|
|
888
|
+
|
|
889
|
+
### twig.purge
|
|
890
|
+
Purges the current, typically used after element has been processed.<br>The root object cannot be purged.
|
|
891
|
+
|
|
892
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
893
|
+
<a name="Twig+purgeUpTo"></a>
|
|
894
|
+
|
|
895
|
+
### twig.purgeUpTo
|
|
896
|
+
Purges up to the elt element. This allows you to keep part of the tree in memory when you purge.
|
|
897
|
+
|
|
898
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
899
|
+
|
|
900
|
+
| Param | Type | Description |
|
|
901
|
+
| --- | --- | --- |
|
|
902
|
+
| elt | [<code>Twig</code>](#Twig) | Up to this element the tree will be purged. The `elt` object itself is not purged.<br> If `undefined` then the current element is purged (i.e. `purge()`) |
|
|
903
|
+
|
|
904
|
+
<a name="Twig+escapeEntity"></a>
|
|
905
|
+
|
|
906
|
+
### twig.escapeEntity
|
|
907
|
+
Escapes special XML characters. According W3C specification these are only `&, <, >, ", '` - this is a XML parser, not HTML!
|
|
908
|
+
|
|
909
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
910
|
+
|
|
911
|
+
| Param | Type | Description |
|
|
912
|
+
| --- | --- | --- |
|
|
913
|
+
| text | <code>string</code> | Input text to be escaped |
|
|
914
|
+
|
|
848
915
|
<a name="Twig+isEmpty"></a>
|
|
849
916
|
|
|
850
917
|
### twig.isEmpty ⇒ <code>boolean</code>
|
|
@@ -904,17 +971,17 @@ The text of the element. No matter if given as text or CDATA entity
|
|
|
904
971
|
<a name="Twig+text"></a>
|
|
905
972
|
|
|
906
973
|
### twig.text
|
|
907
|
-
|
|
974
|
+
Update the text of the element
|
|
908
975
|
|
|
909
976
|
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
910
977
|
**Throws**:
|
|
911
978
|
|
|
912
|
-
- [<code>UnsupportedType</code>](#UnsupportedType) - If value is not a string or numeric type
|
|
979
|
+
- [<code>UnsupportedType</code>](#UnsupportedType) - If value is not a string, boolean or numeric type
|
|
913
980
|
|
|
914
981
|
|
|
915
982
|
| Param | Type | Description |
|
|
916
983
|
| --- | --- | --- |
|
|
917
|
-
| value | <code>string</code> | New
|
|
984
|
+
| value | <code>string</code> \| <code>number</code> \| <code>bigint</code> \| <code>boolean</code> | New text of the element |
|
|
918
985
|
|
|
919
986
|
<a name="Twig+pin"></a>
|
|
920
987
|
|
|
@@ -929,21 +996,6 @@ Checks if element is pinned
|
|
|
929
996
|
|
|
930
997
|
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
931
998
|
**Returns**: <code>boolean</code> - `true` when the element is pinned
|
|
932
|
-
<a name="Twig+text"></a>
|
|
933
|
-
|
|
934
|
-
### twig.text
|
|
935
|
-
Modifies the text of the element
|
|
936
|
-
|
|
937
|
-
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
938
|
-
**Throws**:
|
|
939
|
-
|
|
940
|
-
- [<code>UnsupportedType</code>](#UnsupportedType) - If value is not a string or numeric type
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
| Param | Type | Description |
|
|
944
|
-
| --- | --- | --- |
|
|
945
|
-
| value | <code>string</code> | New value of the attribute |
|
|
946
|
-
|
|
947
999
|
<a name="Twig+close"></a>
|
|
948
1000
|
|
|
949
1001
|
### twig.close
|
|
@@ -1008,7 +1060,7 @@ Check if the attribute exist or not
|
|
|
1008
1060
|
<a name="Twig+attribute"></a>
|
|
1009
1061
|
|
|
1010
1062
|
### twig.attribute ⇒ <code>object</code>
|
|
1011
|
-
Retrieve or update XML attribute.
|
|
1063
|
+
Retrieve or update XML attribute. For update, the condition must be a string, i.e. must match to one attribute only.
|
|
1012
1064
|
|
|
1013
1065
|
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
1014
1066
|
**Returns**: <code>object</code> - Attributes or `null` if no matching attribute found
|
|
@@ -1016,12 +1068,23 @@ Retrieve or update XML attribute.
|
|
|
1016
1068
|
| Param | Type | Description |
|
|
1017
1069
|
| --- | --- | --- |
|
|
1018
1070
|
| condition | [<code>AttributeCondition</code>](#AttributeCondition) | Optional condition to select attributes |
|
|
1019
|
-
|
|
|
1071
|
+
| value | <code>string</code> \| <code>number</code> \| <code>bigint</code> \| <code>boolean</code> | New value of the attribute.<br>If `undefined` then existing attributes is returned. |
|
|
1020
1072
|
|
|
1021
1073
|
**Example**
|
|
1022
1074
|
```js
|
|
1023
1075
|
attribute((name, val) => { return name === 'age' && val > 50})
|
|
1024
1076
|
```
|
|
1077
|
+
<a name="Twig+deleteAttribute"></a>
|
|
1078
|
+
|
|
1079
|
+
### twig.deleteAttribute
|
|
1080
|
+
Delete the attribute
|
|
1081
|
+
|
|
1082
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
1083
|
+
|
|
1084
|
+
| Param | Type | Description |
|
|
1085
|
+
| --- | --- | --- |
|
|
1086
|
+
| name | <code>string</code> | The attribute name |
|
|
1087
|
+
|
|
1025
1088
|
<a name="Twig+root"></a>
|
|
1026
1089
|
|
|
1027
1090
|
### twig.root ⇒ [<code>Twig</code>](#Twig)
|
|
@@ -1248,23 +1311,27 @@ Find a specific element within current element. Same as `.descendant(condition)[
|
|
|
1248
1311
|
| --- | --- | --- |
|
|
1249
1312
|
| condition | [<code>ElementCondition</code>](#ElementCondition) | Find condition |
|
|
1250
1313
|
|
|
1251
|
-
<a name="Twig+
|
|
1252
|
-
|
|
1253
|
-
### twig.purge()
|
|
1254
|
-
Purges the current, typically used after element has been processed.<br>The root object cannot be purged.
|
|
1314
|
+
<a name="Twig+addElement"></a>
|
|
1255
1315
|
|
|
1256
|
-
|
|
1257
|
-
|
|
1316
|
+
### twig.addElement ⇒ [<code>Twig</code>](#Twig)
|
|
1317
|
+
Add a new element in the current element
|
|
1258
1318
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
**Kind**: instance method of [<code>Twig</code>](#Twig)
|
|
1319
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
1320
|
+
**Returns**: [<code>Twig</code>](#Twig) - - The appended element
|
|
1263
1321
|
|
|
1264
1322
|
| Param | Type | Description |
|
|
1265
1323
|
| --- | --- | --- |
|
|
1266
|
-
|
|
|
1324
|
+
| name | <code>string</code> | The tag name |
|
|
1325
|
+
| text | <code>string</code> | Text of the element |
|
|
1326
|
+
| attributes | <code>object</code> | Element attributes |
|
|
1327
|
+
| position | <code>name</code> \| <code>number</code> | Position name 'first', 'last' or the position in the `children` |
|
|
1328
|
+
|
|
1329
|
+
<a name="Twig+delete"></a>
|
|
1267
1330
|
|
|
1331
|
+
### twig.delete
|
|
1332
|
+
Deletes the current element from tree, same as `purge()`. The root object cannot be deleted.
|
|
1333
|
+
|
|
1334
|
+
**Kind**: instance property of [<code>Twig</code>](#Twig)
|
|
1268
1335
|
<a name="Twig+setRoot"></a>
|
|
1269
1336
|
|
|
1270
1337
|
### twig.setRoot(name) ℗
|
|
@@ -1303,6 +1370,12 @@ Common function to filter Twig element
|
|
|
1303
1370
|
| element | [<code>Twig</code>](#Twig) | Element you like to filter |
|
|
1304
1371
|
| condition | [<code>ElementCondition</code>](#ElementCondition) | The filter condition |
|
|
1305
1372
|
|
|
1373
|
+
<a name="NotImplementedYet"></a>
|
|
1374
|
+
|
|
1375
|
+
## NotImplementedYet
|
|
1376
|
+
Generic error for non implemented feature
|
|
1377
|
+
|
|
1378
|
+
**Kind**: global class
|
|
1306
1379
|
<a name="UnsupportedParser"></a>
|
|
1307
1380
|
|
|
1308
1381
|
## UnsupportedParser
|
package/package.json
CHANGED
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
},
|
|
6
6
|
"name": "xml-twig",
|
|
7
7
|
"description": "Node module for processing huge XML documents in tree mode",
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.2.0",
|
|
9
9
|
"main": "twig.js",
|
|
10
10
|
"directories": {
|
|
11
11
|
"doc": "doc"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"jsdoc-to-markdown": "^8.0.0",
|
|
15
14
|
"luxon": "^2.1.1",
|
|
16
15
|
"node-expat": "^2.4.0"
|
|
17
16
|
},
|
package/samples/sample.js
CHANGED
|
@@ -86,3 +86,11 @@ function rootHandler(elt) {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
|
|
89
|
+
function bookHandler(elt) {
|
|
90
|
+
if (elt.attr('category') == 'fantasy') {
|
|
91
|
+
console.log(elt.writer(true).toString());
|
|
92
|
+
let t = elt.addElement('newTag', 'some Text > more', {id:1},2);
|
|
93
|
+
console.log(t.writer(true).toString());
|
|
94
|
+
console.log(elt.root().writer(true).toString());
|
|
95
|
+
}
|
|
96
|
+
}
|
package/twig.js
CHANGED
|
@@ -123,7 +123,6 @@ function createParser(handler, options) {
|
|
|
123
123
|
enumerable: true,
|
|
124
124
|
get() { return parser._parser.column + 1 }
|
|
125
125
|
});
|
|
126
|
-
parser.underlyingParser = parser._parser;
|
|
127
126
|
|
|
128
127
|
closeEvent = "closetag";
|
|
129
128
|
parser.on("opentagstart", function (node) {
|
|
@@ -199,7 +198,7 @@ function createParser(handler, options) {
|
|
|
199
198
|
}
|
|
200
199
|
})
|
|
201
200
|
parser.on("cdata", function (str) {
|
|
202
|
-
current.text = str;
|
|
201
|
+
current.text = current.text ?? '' + str;
|
|
203
202
|
})
|
|
204
203
|
|
|
205
204
|
let hndl = Array.isArray(handler) ? handler : [handler];
|
|
@@ -221,7 +220,6 @@ function createParser(handler, options) {
|
|
|
221
220
|
enumerable: true,
|
|
222
221
|
get() { return parser.parser.getCurrentColumnNumber() }
|
|
223
222
|
});
|
|
224
|
-
parser.underlyingParser = parser.parser;
|
|
225
223
|
closeEvent = "endElement";
|
|
226
224
|
|
|
227
225
|
parser.on("startElement", function (name, attrs) {
|
|
@@ -320,7 +318,7 @@ function createParser(handler, options) {
|
|
|
320
318
|
|
|
321
319
|
// Common events
|
|
322
320
|
parser.on('text', function (str) {
|
|
323
|
-
current.text = options.trim ? str.trim() : str;
|
|
321
|
+
current.text = current.text ?? '' + options.trim ? str.trim() : str;
|
|
324
322
|
})
|
|
325
323
|
|
|
326
324
|
parser.on("comment", function (str) {
|
|
@@ -352,7 +350,6 @@ function createParser(handler, options) {
|
|
|
352
350
|
return parser;
|
|
353
351
|
}
|
|
354
352
|
|
|
355
|
-
|
|
356
353
|
/**
|
|
357
354
|
* Generic class modeling a XML Node
|
|
358
355
|
* @class Twig
|
|
@@ -435,9 +432,12 @@ class Twig {
|
|
|
435
432
|
* @param {string} name - The name of the XML element
|
|
436
433
|
* @param {Twig} parent - The parent object
|
|
437
434
|
* @param {?object} attributes - Attribute object
|
|
435
|
+
* @param {string|number} index - Position name 'first', 'last' or the position in the current `children` array.<br>Defaults to 'last'
|
|
438
436
|
*/
|
|
439
|
-
constructor(name, parent, attributes) {
|
|
440
|
-
|
|
437
|
+
constructor(name, parent, attributes, index) {
|
|
438
|
+
if (index === undefined)
|
|
439
|
+
current = this;
|
|
440
|
+
|
|
441
441
|
if (name === null) {
|
|
442
442
|
// Root element not available yet
|
|
443
443
|
tree = this;
|
|
@@ -452,7 +452,16 @@ class Twig {
|
|
|
452
452
|
this.#parent = parent;
|
|
453
453
|
if (this.#parent.#pinned)
|
|
454
454
|
this.#pinned = true;
|
|
455
|
-
|
|
455
|
+
if (index === 'last' || index === undefined) {
|
|
456
|
+
parent.#children.push(this);
|
|
457
|
+
} else if (index === 'first') {
|
|
458
|
+
parent.#children.unshift(this);
|
|
459
|
+
} else if (typeof index === 'number') {
|
|
460
|
+
parent.#children = parent.#children.slice(0, index).concat(this, parent.#children.slice(index));
|
|
461
|
+
} else {
|
|
462
|
+
parent.#children.push(this);
|
|
463
|
+
}
|
|
464
|
+
|
|
456
465
|
}
|
|
457
466
|
}
|
|
458
467
|
}
|
|
@@ -460,7 +469,7 @@ class Twig {
|
|
|
460
469
|
/**
|
|
461
470
|
* Purges the current, typically used after element has been processed.<br>The root object cannot be purged.
|
|
462
471
|
*/
|
|
463
|
-
purge() {
|
|
472
|
+
purge = function () {
|
|
464
473
|
if (!this.isRoot)
|
|
465
474
|
this.#parent.#children = this.#parent.#children.filter(x => !Object.is(this, x));
|
|
466
475
|
}
|
|
@@ -470,7 +479,7 @@ class Twig {
|
|
|
470
479
|
* @param {Twig} elt - Up to this element the tree will be purged. The `elt` object itself is not purged.<br>
|
|
471
480
|
* If `undefined` then the current element is purged (i.e. `purge()`)
|
|
472
481
|
*/
|
|
473
|
-
purgeUpTo(elt) {
|
|
482
|
+
purgeUpTo = function (elt) {
|
|
474
483
|
if (elt === undefined) {
|
|
475
484
|
this.purge();
|
|
476
485
|
} else {
|
|
@@ -486,6 +495,19 @@ class Twig {
|
|
|
486
495
|
}
|
|
487
496
|
}
|
|
488
497
|
|
|
498
|
+
/**
|
|
499
|
+
* Escapes special XML characters. According W3C specification these are only `&, <, >, ", '` - this is a XML parser, not HTML!
|
|
500
|
+
* @param {string} text - Input text to be escaped
|
|
501
|
+
*/
|
|
502
|
+
escapeEntity = function (text) {
|
|
503
|
+
return text
|
|
504
|
+
.replaceAll("&", "&")
|
|
505
|
+
.replaceAll("<", "<")
|
|
506
|
+
.replaceAll(">", ">")
|
|
507
|
+
.replaceAll('"', """)
|
|
508
|
+
.replaceAll("'", "'");
|
|
509
|
+
}
|
|
510
|
+
|
|
489
511
|
/**
|
|
490
512
|
* Sets the name of root element. In some cases the root is created before the XML-Root element is available<br>
|
|
491
513
|
* Used internally!
|
|
@@ -568,14 +590,17 @@ class Twig {
|
|
|
568
590
|
}
|
|
569
591
|
|
|
570
592
|
/**
|
|
571
|
-
*
|
|
572
|
-
* @param {string} value - New
|
|
573
|
-
* @throws {UnsupportedType} - If value is not a string or numeric type
|
|
593
|
+
* Update the text of the element
|
|
594
|
+
* @param {string|number|bigint|boolean} value - New text of the element
|
|
595
|
+
* @throws {UnsupportedType} - If value is not a string, boolean or numeric type
|
|
574
596
|
*/
|
|
575
597
|
set text(value) {
|
|
576
|
-
if (
|
|
598
|
+
if (typeof value === 'string')
|
|
599
|
+
this.#text = value
|
|
600
|
+
else if (['number', 'bigint', 'boolean'].includes(typeof value))
|
|
601
|
+
this.#text = value.toString()
|
|
602
|
+
else
|
|
577
603
|
throw new UnsupportedType(value);
|
|
578
|
-
this.#text = this.#text ?? '' + value;
|
|
579
604
|
}
|
|
580
605
|
|
|
581
606
|
/**
|
|
@@ -593,18 +618,6 @@ class Twig {
|
|
|
593
618
|
return this.#pinned;
|
|
594
619
|
}
|
|
595
620
|
|
|
596
|
-
/**
|
|
597
|
-
* Modifies the text of the element
|
|
598
|
-
* @param {string} value - New value of the attribute
|
|
599
|
-
* @throws {UnsupportedType} - If value is not a string or numeric type
|
|
600
|
-
*/
|
|
601
|
-
set text(value) {
|
|
602
|
-
if (!['string', 'number', 'bigint'].includes(typeof value))
|
|
603
|
-
throw new UnsupportedType(value);
|
|
604
|
-
this.#text = this.#text ?? '' + value;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
|
|
608
621
|
/**
|
|
609
622
|
* Closes the element
|
|
610
623
|
*/
|
|
@@ -681,17 +694,17 @@ class Twig {
|
|
|
681
694
|
}
|
|
682
695
|
|
|
683
696
|
/**
|
|
684
|
-
* Retrieve or update XML attribute.
|
|
697
|
+
* Retrieve or update XML attribute. For update, the condition must be a string, i.e. must match to one attribute only.
|
|
685
698
|
* @param {?AttributeCondition} condition - Optional condition to select attributes
|
|
686
|
-
* @param {?string|number}
|
|
699
|
+
* @param {?string|number|bigint|boolean} value - New value of the attribute.<br>If `undefined` then existing attributes is returned.
|
|
687
700
|
* @returns {object} Attributes or `null` if no matching attribute found
|
|
688
701
|
* @example attribute((name, val) => { return name === 'age' && val > 50})
|
|
689
702
|
* attribute((name) => { return ['firstName', 'lastName'].includes(name) })
|
|
690
703
|
* attribute('firstName')
|
|
691
704
|
* attribute(/name/i)
|
|
692
705
|
*/
|
|
693
|
-
attribute = function (condition,
|
|
694
|
-
if (
|
|
706
|
+
attribute = function (condition, value) {
|
|
707
|
+
if (value === undefined) {
|
|
695
708
|
let attr;
|
|
696
709
|
if (condition === undefined) {
|
|
697
710
|
attr = this.#attributes;
|
|
@@ -707,19 +720,26 @@ class Twig {
|
|
|
707
720
|
return this.attribute();
|
|
708
721
|
}
|
|
709
722
|
return attr === null || Object.keys(attr).length == 0 ? null : attr;
|
|
723
|
+
} else if (typeof condition === 'string') {
|
|
724
|
+
if (typeof value === 'string')
|
|
725
|
+
this.#attributes[condition] = value
|
|
726
|
+
else if (['number', 'bigint', 'boolean'].includes(typeof value))
|
|
727
|
+
this.#attributes[condition] = value.toString()
|
|
728
|
+
else
|
|
729
|
+
throw new UnsupportedType(value);
|
|
710
730
|
} else {
|
|
711
|
-
if
|
|
712
|
-
delete this.#attributes[condition];
|
|
713
|
-
} else {
|
|
714
|
-
if (!['string', 'number', 'bigint'].includes(typeof text))
|
|
715
|
-
throw new UnsupportedType(text);
|
|
716
|
-
if (typeof condition !== 'string')
|
|
717
|
-
throw new UnsupportedCondition(condition, ['string']);
|
|
718
|
-
this.#attributes[condition] = text;
|
|
719
|
-
}
|
|
731
|
+
console.warn('Condition must be a `string` if you like to update an attribute');
|
|
720
732
|
}
|
|
721
733
|
}
|
|
722
734
|
|
|
735
|
+
/**
|
|
736
|
+
* Delete the attribute
|
|
737
|
+
* @param {string} name - The attribute name
|
|
738
|
+
*/
|
|
739
|
+
deleteAttribute = function (name) {
|
|
740
|
+
delete this.#attributes[name];
|
|
741
|
+
}
|
|
742
|
+
|
|
723
743
|
/**
|
|
724
744
|
* Returns the root object
|
|
725
745
|
* @returns {Twig} The root element of XML tree
|
|
@@ -1068,6 +1088,40 @@ class Twig {
|
|
|
1068
1088
|
return null;
|
|
1069
1089
|
}
|
|
1070
1090
|
|
|
1091
|
+
/**
|
|
1092
|
+
* Add a new element in the current element
|
|
1093
|
+
* @param {string} name - The tag name
|
|
1094
|
+
* @param {?string} text - Text of the element
|
|
1095
|
+
* @param {?object} attributes - Element attributes
|
|
1096
|
+
* @param {name|number} position - Position name 'first', 'last' or the position in the `children`
|
|
1097
|
+
* @returns {Twig} - The appended element
|
|
1098
|
+
*/
|
|
1099
|
+
addElement = function (name, text, attributes, position) {
|
|
1100
|
+
let twig = new Twig(name, this, attributes ?? {}, position ?? 'last');
|
|
1101
|
+
twig.#text = text ?? null;
|
|
1102
|
+
twig.close();
|
|
1103
|
+
return twig;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* Deletes the current element from tree, same as `purge()`. The root object cannot be deleted.
|
|
1108
|
+
*/
|
|
1109
|
+
delete = function () {
|
|
1110
|
+
this.purge();
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* Generic error for non implemented feature
|
|
1119
|
+
* @exception NotImplementedYet
|
|
1120
|
+
*/
|
|
1121
|
+
class NotImplementedYet extends TypeError {
|
|
1122
|
+
constructor() {
|
|
1123
|
+
super(`Net yet implemented`);
|
|
1124
|
+
}
|
|
1071
1125
|
}
|
|
1072
1126
|
|
|
1073
1127
|
|
|
@@ -1084,7 +1138,6 @@ class UnsupportedParser extends TypeError {
|
|
|
1084
1138
|
}
|
|
1085
1139
|
}
|
|
1086
1140
|
|
|
1087
|
-
|
|
1088
1141
|
/**
|
|
1089
1142
|
* Generic error for unsupported data types
|
|
1090
1143
|
* @exception UnsupportedType
|
|
@@ -1112,5 +1165,6 @@ class UnsupportedCondition extends TypeError {
|
|
|
1112
1165
|
}
|
|
1113
1166
|
}
|
|
1114
1167
|
|
|
1168
|
+
|
|
1115
1169
|
module.exports = { createParser, Twig, Any, Root };
|
|
1116
1170
|
|