@cntwg/xml-lib-js 0.0.24 → 0.0.26
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/CHANGELOG.md +19 -0
- package/LICENSE +1 -1
- package/README.md +17 -10
- package/doc/xmldoc-lib.md +104 -49
- package/index.js +13 -16
- package/lib/xml-helper.js +88 -0
- package/lib/xmldoc-lib.js +462 -84
- package/package.json +12 -7
package/lib/xmldoc-lib.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// [v0.1.
|
|
1
|
+
// [v0.1.077-20240625]
|
|
2
2
|
|
|
3
3
|
// === module init block ===
|
|
4
4
|
|
|
@@ -9,12 +9,50 @@ const xmlParser = require('@ygracs/xml-js6');
|
|
|
9
9
|
const {
|
|
10
10
|
valueToIndex, readAsBool, readAsString, isNotEmptyString,
|
|
11
11
|
isArray, isObject, isPlainObject,
|
|
12
|
-
valueToArray,
|
|
12
|
+
valueToArray, valueToEntry,
|
|
13
13
|
} = require('@ygracs/bsfoc-lib-js');
|
|
14
14
|
|
|
15
15
|
const xObj = require('@ygracs/xobj-lib-js');
|
|
16
|
-
const
|
|
17
|
-
|
|
16
|
+
const {
|
|
17
|
+
TXmlContentParseOptions,
|
|
18
|
+
DEF_XML_PARSE_OPTIONS: XML_DEF_PARSE_OPTIONS,
|
|
19
|
+
} = xObj;
|
|
20
|
+
|
|
21
|
+
// === module extra block (helper functions) ===
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @function checkFsError
|
|
25
|
+
* @param {object}
|
|
26
|
+
* @param {Error}
|
|
27
|
+
* @returns {object}
|
|
28
|
+
* @inner
|
|
29
|
+
* @description Checs an error code of a fs ops and sets descr info if succeed
|
|
30
|
+
*/
|
|
31
|
+
function checkFsError(descr, err) {
|
|
32
|
+
let isSucceed = false;
|
|
33
|
+
if (isPlainObject(err) && isPlainObject(descr)) {
|
|
34
|
+
switch (err.code) {
|
|
35
|
+
case 'ENOENT':
|
|
36
|
+
case 'EISDIR':
|
|
37
|
+
case 'EPERM': {
|
|
38
|
+
descr.errCode = err.errno;
|
|
39
|
+
descr.errEvent = err.code;
|
|
40
|
+
descr.errMsg = `ERR_FILE_${err.code}`;
|
|
41
|
+
isSucceed = true;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
default: {}
|
|
45
|
+
};
|
|
46
|
+
if (isSucceed) descr.isERR = true;
|
|
47
|
+
};
|
|
48
|
+
return { isSucceed, descr };
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// === module main block ===
|
|
52
|
+
|
|
53
|
+
/***
|
|
54
|
+
* (* constant definitions *)
|
|
55
|
+
*/
|
|
18
56
|
|
|
19
57
|
const XML_DEF_ROOT_ETAG_NAME = 'root';
|
|
20
58
|
const XML_LANG_ATTR_TNAME = 'lang';
|
|
@@ -24,16 +62,27 @@ const XML_TE_NOBJ_EMSG = `${XML_TE_INVARG_EMSG} (an object is expected)`;
|
|
|
24
62
|
const XML_TE_NARR_EMSG = `${XML_TE_INVARG_EMSG} (an array is expected)`;
|
|
25
63
|
const XML_TE_NROOT_EMSG = 'root element not found';
|
|
26
64
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
65
|
+
/***
|
|
66
|
+
* (* function definitions *)
|
|
67
|
+
*/
|
|
30
68
|
|
|
31
|
-
|
|
69
|
+
/***
|
|
70
|
+
* (* class definitions *)
|
|
71
|
+
*/
|
|
32
72
|
|
|
73
|
+
/**
|
|
74
|
+
* @description This class implements an attributes mapper instance
|
|
75
|
+
*/
|
|
33
76
|
class TXmlAttributesMapper {
|
|
34
77
|
#_host = null;
|
|
35
78
|
#_options = null;
|
|
36
79
|
|
|
80
|
+
/**
|
|
81
|
+
* @param {object}
|
|
82
|
+
* @param {object} [opt]
|
|
83
|
+
* @param {object} [opt.parseOptions]
|
|
84
|
+
* @throws {TypeError}
|
|
85
|
+
*/
|
|
37
86
|
constructor(obj, opt){
|
|
38
87
|
// init an elements content
|
|
39
88
|
if (!isPlainObject(obj)) throw new TypeError(XML_TE_NOBJ_EMSG);
|
|
@@ -58,6 +107,10 @@ class TXmlAttributesMapper {
|
|
|
58
107
|
this.#_options = parseOptions;
|
|
59
108
|
}
|
|
60
109
|
|
|
110
|
+
/**
|
|
111
|
+
* @property {array}
|
|
112
|
+
* @readonly
|
|
113
|
+
*/
|
|
61
114
|
get entries(){
|
|
62
115
|
let items = xObj.getXObjAttributes(
|
|
63
116
|
this.#_host,
|
|
@@ -66,6 +119,11 @@ class TXmlAttributesMapper {
|
|
|
66
119
|
return isPlainObject(items) ? Object.entries(items) : [];
|
|
67
120
|
}
|
|
68
121
|
|
|
122
|
+
/**
|
|
123
|
+
* @param {ID_STRING}
|
|
124
|
+
* @returns {bool}
|
|
125
|
+
* @description Checks whether an attribute exists.
|
|
126
|
+
*/
|
|
69
127
|
hasAttribute(name){
|
|
70
128
|
let result = false;
|
|
71
129
|
try {
|
|
@@ -81,6 +139,11 @@ class TXmlAttributesMapper {
|
|
|
81
139
|
return result;
|
|
82
140
|
}
|
|
83
141
|
|
|
142
|
+
/**
|
|
143
|
+
* @param {ID_STRING}
|
|
144
|
+
* @returns {string}
|
|
145
|
+
* @description Returns an attribute value.
|
|
146
|
+
*/
|
|
84
147
|
getAttribute(name){
|
|
85
148
|
let result = '';
|
|
86
149
|
try {
|
|
@@ -96,6 +159,12 @@ class TXmlAttributesMapper {
|
|
|
96
159
|
return result;
|
|
97
160
|
}
|
|
98
161
|
|
|
162
|
+
/**
|
|
163
|
+
* @param {ID_STRING}
|
|
164
|
+
* @param {any}
|
|
165
|
+
* @returns {bool}
|
|
166
|
+
* @description Sets an attribute value.
|
|
167
|
+
*/
|
|
99
168
|
setAttribute(name, value){
|
|
100
169
|
let result = false;
|
|
101
170
|
try {
|
|
@@ -112,6 +181,11 @@ class TXmlAttributesMapper {
|
|
|
112
181
|
return result;
|
|
113
182
|
}
|
|
114
183
|
|
|
184
|
+
/**
|
|
185
|
+
* @param {ID_STRING}
|
|
186
|
+
* @returns {bool}
|
|
187
|
+
* @description Deletes an attribute.
|
|
188
|
+
*/
|
|
115
189
|
delAttribute(name){
|
|
116
190
|
let result = false;
|
|
117
191
|
try {
|
|
@@ -127,6 +201,10 @@ class TXmlAttributesMapper {
|
|
|
127
201
|
return result;
|
|
128
202
|
}
|
|
129
203
|
|
|
204
|
+
/**
|
|
205
|
+
* @returns {none}
|
|
206
|
+
* @description Deletes all attributes.
|
|
207
|
+
*/
|
|
130
208
|
clear(){
|
|
131
209
|
xObj.insertXObjElement(
|
|
132
210
|
this.#_host,
|
|
@@ -140,6 +218,9 @@ class TXmlAttributesMapper {
|
|
|
140
218
|
|
|
141
219
|
}
|
|
142
220
|
|
|
221
|
+
/**
|
|
222
|
+
* @description This class implements an instance of an element controller
|
|
223
|
+
*/
|
|
143
224
|
class TXmlElementController {
|
|
144
225
|
#_host = null;
|
|
145
226
|
#_options = null;
|
|
@@ -147,6 +228,13 @@ class TXmlElementController {
|
|
|
147
228
|
#_attributes = null;
|
|
148
229
|
#_name = null;
|
|
149
230
|
|
|
231
|
+
/**
|
|
232
|
+
* @param {object}
|
|
233
|
+
* @param {object} [opt]
|
|
234
|
+
* @param {object} [opt.parseOptions]
|
|
235
|
+
* @param {bool} [opt.proxyModeEnable=false]
|
|
236
|
+
* @throws {TypeError}
|
|
237
|
+
*/
|
|
150
238
|
constructor(obj, opt){
|
|
151
239
|
// load options
|
|
152
240
|
let _options = isPlainObject(opt) ? opt : {};
|
|
@@ -190,10 +278,19 @@ class TXmlElementController {
|
|
|
190
278
|
this.#_attributes = new TXmlAttributesMapper(obj, _options);
|
|
191
279
|
}
|
|
192
280
|
|
|
281
|
+
/**
|
|
282
|
+
* @property {TXmlAttributesMapper}
|
|
283
|
+
* @readonly
|
|
284
|
+
*/
|
|
193
285
|
get attributes(){
|
|
194
286
|
return this.#_attributes;
|
|
195
287
|
}
|
|
196
288
|
|
|
289
|
+
/**
|
|
290
|
+
* @property {string}
|
|
291
|
+
* @readonly
|
|
292
|
+
* @experimental
|
|
293
|
+
*/
|
|
197
294
|
get name(){
|
|
198
295
|
let result = '';
|
|
199
296
|
if (this.#_parseOptions.settings.compact) {
|
|
@@ -207,6 +304,9 @@ class TXmlElementController {
|
|
|
207
304
|
return result;
|
|
208
305
|
}
|
|
209
306
|
|
|
307
|
+
/**
|
|
308
|
+
* @property {string}
|
|
309
|
+
*/
|
|
210
310
|
get textValue(){
|
|
211
311
|
return xObj.readXObjParam(this.#_host, this.#_parseOptions.settings.textKey);
|
|
212
312
|
}
|
|
@@ -215,22 +315,44 @@ class TXmlElementController {
|
|
|
215
315
|
xObj.writeXObjParam(this.#_host, value, this.#_parseOptions.settings.textKey);
|
|
216
316
|
}
|
|
217
317
|
|
|
318
|
+
/**
|
|
319
|
+
* @param {ID_STRING}
|
|
320
|
+
* @returns {bool}
|
|
321
|
+
* @description Checks whether an attribute exists.
|
|
322
|
+
*/
|
|
218
323
|
hasAttribute(name){
|
|
219
324
|
return this.#_attributes.hasAttribute(name);
|
|
220
325
|
}
|
|
221
326
|
|
|
327
|
+
/**
|
|
328
|
+
* @param {ID_STRING}
|
|
329
|
+
* @returns {string}
|
|
330
|
+
* @description Returns an attribute value.
|
|
331
|
+
*/
|
|
222
332
|
getAttribute(name){
|
|
223
333
|
return this.#_attributes.getAttribute(name);
|
|
224
334
|
}
|
|
225
335
|
|
|
336
|
+
/**
|
|
337
|
+
* @see TXmlAttributesMapper.setAttribute
|
|
338
|
+
*/
|
|
226
339
|
setAttribute(...args){
|
|
227
340
|
return this.#_attributes.setAttribute(...args);
|
|
228
341
|
}
|
|
229
342
|
|
|
343
|
+
/**
|
|
344
|
+
* @param {ID_STRING}
|
|
345
|
+
* @returns {bool}
|
|
346
|
+
* @description Deletes an attribute.
|
|
347
|
+
*/
|
|
230
348
|
delAttribute(name){
|
|
231
349
|
return this.#_attributes.delAttribute(name);
|
|
232
350
|
}
|
|
233
351
|
|
|
352
|
+
/**
|
|
353
|
+
* @returns {array}
|
|
354
|
+
* @description Returns a text value in format of a `[ <lang>, <text> ]` pair.
|
|
355
|
+
*/
|
|
234
356
|
getTextValue(){
|
|
235
357
|
return [
|
|
236
358
|
this.#_attributes.getAttribute(XML_LANG_ATTR_TNAME),
|
|
@@ -238,30 +360,40 @@ class TXmlElementController {
|
|
|
238
360
|
];
|
|
239
361
|
}
|
|
240
362
|
|
|
363
|
+
/**
|
|
364
|
+
* @param {(string|entry)}
|
|
365
|
+
* @returns {bool}
|
|
366
|
+
* @description Sets a text value.
|
|
367
|
+
*/
|
|
241
368
|
setTextValue(value){
|
|
242
|
-
const _value =
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return
|
|
369
|
+
const _value = valueToEntry(value);
|
|
370
|
+
if (_value !== null) {
|
|
371
|
+
const [ lang, param ] = _value;
|
|
372
|
+
if (xObj.writeXObjParam(
|
|
373
|
+
this.#_host,
|
|
374
|
+
param,
|
|
375
|
+
this.#_parseOptions.settings.textKey,
|
|
376
|
+
)) {
|
|
377
|
+
const attributes = this.#_attributes;
|
|
378
|
+
if (lang === '') {
|
|
379
|
+
if (attributes.hasAttribute(XML_LANG_ATTR_TNAME)) {
|
|
380
|
+
return attributes.delAttribute(XML_LANG_ATTR_TNAME);
|
|
381
|
+
} else {
|
|
382
|
+
return true;
|
|
383
|
+
};
|
|
384
|
+
} else {
|
|
385
|
+
return attributes.setAttribute(XML_LANG_ATTR_TNAME, lang);
|
|
259
386
|
};
|
|
260
387
|
};
|
|
261
388
|
};
|
|
262
389
|
return false;
|
|
263
390
|
}
|
|
264
391
|
|
|
392
|
+
/**
|
|
393
|
+
* @param {ID_STRING}
|
|
394
|
+
* @returns {bool}
|
|
395
|
+
* @description Checks whether an element has a child element.
|
|
396
|
+
*/
|
|
265
397
|
hasChild(name){
|
|
266
398
|
const _name = xObj.evalXObjEName(name);
|
|
267
399
|
let result = false;
|
|
@@ -276,6 +408,11 @@ class TXmlElementController {
|
|
|
276
408
|
return result;
|
|
277
409
|
}
|
|
278
410
|
|
|
411
|
+
/**
|
|
412
|
+
* @param {ID_STRING}
|
|
413
|
+
* @returns {(null|TXmlElementController|TXmlElementsListController)}
|
|
414
|
+
* @description Returns a child element.
|
|
415
|
+
*/
|
|
279
416
|
getChild(name){
|
|
280
417
|
const _name = xObj.evalXObjEName(name);
|
|
281
418
|
let result = null;
|
|
@@ -295,6 +432,12 @@ class TXmlElementController {
|
|
|
295
432
|
return result;
|
|
296
433
|
}
|
|
297
434
|
|
|
435
|
+
/**
|
|
436
|
+
* @param {ID_STRING}
|
|
437
|
+
* @returns {object}
|
|
438
|
+
* @protected
|
|
439
|
+
* @description Returns a child element.
|
|
440
|
+
*/
|
|
298
441
|
_getChildRaw(name){
|
|
299
442
|
//console.log('CHECK: TXmlElementController._getChildRaw() => was called...');
|
|
300
443
|
//console.log('CHECK: TXmlElementController._getChildRaw() => _host => '+JSON.stringify(this.#_host, null, 2));
|
|
@@ -307,11 +450,22 @@ class TXmlElementController {
|
|
|
307
450
|
return item !== undefined ? item : null;
|
|
308
451
|
}
|
|
309
452
|
|
|
453
|
+
/**
|
|
454
|
+
* @see TXmlElementController.__setChildRaw
|
|
455
|
+
* @protected
|
|
456
|
+
* @description Sets a child element.
|
|
457
|
+
*/
|
|
310
458
|
_setChildRaw(...args){
|
|
311
459
|
//console.log('CHECK: TXmlElementController._setChildRaw() => was called...');
|
|
312
460
|
return TXmlElementController.__setChildRaw(this, ...args);
|
|
313
461
|
}
|
|
314
462
|
|
|
463
|
+
/**
|
|
464
|
+
* @param {ID_STRING}
|
|
465
|
+
* @returns {?object}
|
|
466
|
+
* @protected
|
|
467
|
+
* @description Adds a new child element.
|
|
468
|
+
*/
|
|
315
469
|
_addChildRaw(name){//}, obj){
|
|
316
470
|
//console.log('CHECK: TXmlElementController._addChild() => was called...');
|
|
317
471
|
//console.log('CHECK: TXmlElementController._addChildRaw() => _host => '+JSON.stringify(this.#_host, null, 2));
|
|
@@ -324,6 +478,11 @@ class TXmlElementController {
|
|
|
324
478
|
return result.isSucceed ? result.item : null;
|
|
325
479
|
}
|
|
326
480
|
|
|
481
|
+
/**
|
|
482
|
+
* @param {ID_STRING}
|
|
483
|
+
* @returns {?TXmlElementController}
|
|
484
|
+
* @description Adds a new child element.
|
|
485
|
+
*/
|
|
327
486
|
addChild(name){
|
|
328
487
|
const _name = xObj.evalXObjEName(name);
|
|
329
488
|
let result = null;
|
|
@@ -339,6 +498,11 @@ class TXmlElementController {
|
|
|
339
498
|
return result;
|
|
340
499
|
}
|
|
341
500
|
|
|
501
|
+
/**
|
|
502
|
+
* @param {ID_STRING}
|
|
503
|
+
* @returns {bool}
|
|
504
|
+
* @description Deletes a child element.
|
|
505
|
+
*/
|
|
342
506
|
delChild(name){
|
|
343
507
|
const _name = xObj.evalXObjEName(name);
|
|
344
508
|
let isSUCCEED = false;
|
|
@@ -368,14 +532,34 @@ class TXmlElementController {
|
|
|
368
532
|
return isSUCCEED;
|
|
369
533
|
}
|
|
370
534
|
|
|
535
|
+
/**
|
|
536
|
+
* @returns {none}
|
|
537
|
+
* @description Deletes all child elements and attributes.
|
|
538
|
+
*/
|
|
371
539
|
clear(){
|
|
372
540
|
TXmlElementController.clear(this);
|
|
373
541
|
}
|
|
374
542
|
|
|
543
|
+
/**
|
|
544
|
+
* @param {object}
|
|
545
|
+
* @returns {?object}
|
|
546
|
+
* @protected
|
|
547
|
+
* @static
|
|
548
|
+
* @description Tries to unwraps a given object.
|
|
549
|
+
*/
|
|
375
550
|
static __unwrap(item){
|
|
376
551
|
return (item instanceof TXmlElementController) ? item.#_host : null;
|
|
377
552
|
}
|
|
378
553
|
|
|
554
|
+
/**
|
|
555
|
+
* @param {TXmlElementController}
|
|
556
|
+
* @param {ID_STRING}
|
|
557
|
+
* @param {object}
|
|
558
|
+
* @returns {bool}
|
|
559
|
+
* @protected
|
|
560
|
+
* @static
|
|
561
|
+
* @description Sets a child element.
|
|
562
|
+
*/
|
|
379
563
|
static __setChildRaw(node, name, obj){
|
|
380
564
|
//console.log('CHECK: TXmlElementController.__setChildRaw() => was called...');
|
|
381
565
|
let isSUCCEED = false;
|
|
@@ -398,6 +582,12 @@ class TXmlElementController {
|
|
|
398
582
|
return isSUCCEED;
|
|
399
583
|
}
|
|
400
584
|
|
|
585
|
+
/**
|
|
586
|
+
* @param {object}
|
|
587
|
+
* @returns {none}
|
|
588
|
+
* @static
|
|
589
|
+
* @description Tries to clean a given object.
|
|
590
|
+
*/
|
|
401
591
|
static clear(obj){
|
|
402
592
|
let item = TXmlElementController.__unwrap(obj);
|
|
403
593
|
if (item) {
|
|
@@ -410,11 +600,22 @@ class TXmlElementController {
|
|
|
410
600
|
|
|
411
601
|
};
|
|
412
602
|
|
|
603
|
+
/**
|
|
604
|
+
* @description This class implements an instance of a list controller
|
|
605
|
+
*/
|
|
413
606
|
class TXmlElementsListController {
|
|
414
607
|
#_host = null;
|
|
415
608
|
#_options = null;
|
|
416
609
|
#_count = null;
|
|
417
610
|
|
|
611
|
+
/**
|
|
612
|
+
* @param {array}
|
|
613
|
+
* @param {object} [opt]
|
|
614
|
+
* @param {object} [opt.parseOptions]
|
|
615
|
+
* @param {bool} [opt.proxyModeEnable=false]
|
|
616
|
+
* @param {bool} [opt.isNullItemsAllowed=false] - <reserved>
|
|
617
|
+
* @throws {TypeError}
|
|
618
|
+
*/
|
|
418
619
|
constructor(obj, opt){
|
|
419
620
|
// load options
|
|
420
621
|
let _options = isPlainObject(opt) ? opt : {};
|
|
@@ -450,39 +651,78 @@ class TXmlElementsListController {
|
|
|
450
651
|
this.#_options = _options;
|
|
451
652
|
}
|
|
452
653
|
|
|
654
|
+
/**
|
|
655
|
+
* @property {number}
|
|
656
|
+
* @readonly
|
|
657
|
+
*/
|
|
453
658
|
get count(){
|
|
454
659
|
return this.#_host.length;
|
|
455
660
|
}
|
|
456
661
|
|
|
662
|
+
/**
|
|
663
|
+
* @property {number}
|
|
664
|
+
* @readonly
|
|
665
|
+
*/
|
|
457
666
|
get size(){
|
|
458
667
|
return this.#_host.length;
|
|
459
668
|
}
|
|
460
669
|
|
|
670
|
+
/**
|
|
671
|
+
* @property {index}
|
|
672
|
+
* @readonly
|
|
673
|
+
*/
|
|
461
674
|
get maxIndex(){
|
|
462
675
|
return this.#_host.length - 1;
|
|
463
676
|
}
|
|
464
677
|
|
|
678
|
+
/**
|
|
679
|
+
* @property {bool}
|
|
680
|
+
* @readonly
|
|
681
|
+
*/
|
|
465
682
|
get isNullItemsAllowed(){
|
|
466
683
|
return readAsBool(this.#_options.isNullItemsAllowed);
|
|
467
684
|
}
|
|
468
685
|
|
|
686
|
+
/**
|
|
687
|
+
* @returns {none}
|
|
688
|
+
* @description Deletes all child elements and attributes.
|
|
689
|
+
*/
|
|
469
690
|
clear(){
|
|
470
691
|
this.#_host.length = 0;
|
|
471
692
|
}
|
|
472
693
|
|
|
694
|
+
/**
|
|
695
|
+
* @returns {bool}
|
|
696
|
+
* @description Checks whether an instance holds none element.
|
|
697
|
+
*/
|
|
473
698
|
isEmpty(){
|
|
474
699
|
return this.count === 0;
|
|
475
700
|
}
|
|
476
701
|
|
|
702
|
+
/**
|
|
703
|
+
* @returns {bool}
|
|
704
|
+
* @description Checks whether an instance holds at least one element.
|
|
705
|
+
*/
|
|
477
706
|
isNotEmpty(){
|
|
478
707
|
return this.count > 0;
|
|
479
708
|
}
|
|
480
709
|
|
|
710
|
+
/**
|
|
711
|
+
* @param {any}
|
|
712
|
+
* @returns {bool}
|
|
713
|
+
* @description Checks whether a given value is a valid index value
|
|
714
|
+
* and it is not exceeds an index range within the instance.
|
|
715
|
+
*/
|
|
481
716
|
chkIndex(value){
|
|
482
717
|
const index = valueToIndex(value);
|
|
483
718
|
return index !== -1 && index < this.size;
|
|
484
719
|
}
|
|
485
720
|
|
|
721
|
+
/**
|
|
722
|
+
* @param {any}
|
|
723
|
+
* @returns {bool}
|
|
724
|
+
* @description Checks whether or not a given element is valid.
|
|
725
|
+
*/
|
|
486
726
|
isValidItem(obj){
|
|
487
727
|
return (
|
|
488
728
|
(this.#_options.isNullItemsAllowed && obj === null)
|
|
@@ -490,11 +730,22 @@ class TXmlElementsListController {
|
|
|
490
730
|
);
|
|
491
731
|
}
|
|
492
732
|
|
|
733
|
+
/**
|
|
734
|
+
* @param {index}
|
|
735
|
+
* @returns {?object}
|
|
736
|
+
* @protected
|
|
737
|
+
* @description Returns an element.
|
|
738
|
+
*/
|
|
493
739
|
_getItemRaw(index){
|
|
494
740
|
let item = this.#_host[valueToIndex(index)];
|
|
495
741
|
return item !== undefined ? item : null;
|
|
496
742
|
}
|
|
497
743
|
|
|
744
|
+
/**
|
|
745
|
+
* @param {index}
|
|
746
|
+
* @returns {?TXmlElementController}
|
|
747
|
+
* @description Returns an element.
|
|
748
|
+
*/
|
|
498
749
|
getItem(index){
|
|
499
750
|
let item = this.#_host[valueToIndex(index)];
|
|
500
751
|
// wrap item in container
|
|
@@ -505,6 +756,12 @@ class TXmlElementsListController {
|
|
|
505
756
|
);
|
|
506
757
|
}
|
|
507
758
|
|
|
759
|
+
/**
|
|
760
|
+
* @param {any}
|
|
761
|
+
* @returns {index}
|
|
762
|
+
* @protected
|
|
763
|
+
* @description Adds a new element.
|
|
764
|
+
*/
|
|
508
765
|
_addItemRaw(item){
|
|
509
766
|
let index = -1;
|
|
510
767
|
if (this.isValidItem(item)) {
|
|
@@ -514,6 +771,11 @@ class TXmlElementsListController {
|
|
|
514
771
|
return index;
|
|
515
772
|
}
|
|
516
773
|
|
|
774
|
+
/**
|
|
775
|
+
* @param {any}
|
|
776
|
+
* @returns {index}
|
|
777
|
+
* @description Adds a new element.
|
|
778
|
+
*/
|
|
517
779
|
addItem(item){
|
|
518
780
|
// unwrap item from container
|
|
519
781
|
if (item instanceof TXmlElementController) {
|
|
@@ -522,12 +784,25 @@ class TXmlElementsListController {
|
|
|
522
784
|
return this._addItemRaw(item);
|
|
523
785
|
}
|
|
524
786
|
|
|
787
|
+
/**
|
|
788
|
+
* @param {index}
|
|
789
|
+
* @param {any}
|
|
790
|
+
* @returns {bool}
|
|
791
|
+
* @protected
|
|
792
|
+
* @description Sets a new element.
|
|
793
|
+
*/
|
|
525
794
|
_setItemRaw(index, item){
|
|
526
795
|
let isSUCCEED = this.chkIndex(index) && this.isValidItem(item);
|
|
527
796
|
if (isSUCCEED) this.#_host[Number(index)] = item; // // TODO: correct count
|
|
528
797
|
return isSUCCEED;
|
|
529
798
|
}
|
|
530
799
|
|
|
800
|
+
/**
|
|
801
|
+
* @param {index}
|
|
802
|
+
* @param {any}
|
|
803
|
+
* @returns {bool}
|
|
804
|
+
* @description Sets a new element.
|
|
805
|
+
*/
|
|
531
806
|
setItem(index, item){
|
|
532
807
|
// unwrap item from container
|
|
533
808
|
if (item instanceof TXmlElementController) {
|
|
@@ -536,6 +811,13 @@ class TXmlElementsListController {
|
|
|
536
811
|
return this._setItemRaw(index, item);
|
|
537
812
|
}
|
|
538
813
|
|
|
814
|
+
/**
|
|
815
|
+
* @param {index}
|
|
816
|
+
* @param {any}
|
|
817
|
+
* @returns {bool}
|
|
818
|
+
* @protected
|
|
819
|
+
* @description Insertes a new element.
|
|
820
|
+
*/
|
|
539
821
|
_insItemRaw(index, item){
|
|
540
822
|
index = valueToIndex(index);
|
|
541
823
|
let size = this.size;
|
|
@@ -556,6 +838,12 @@ class TXmlElementsListController {
|
|
|
556
838
|
return isSUCCEED;
|
|
557
839
|
}
|
|
558
840
|
|
|
841
|
+
/**
|
|
842
|
+
* @param {index}
|
|
843
|
+
* @param {any}
|
|
844
|
+
* @returns {bool}
|
|
845
|
+
* @description Insertes a new element.
|
|
846
|
+
*/
|
|
559
847
|
insItem(index, item){
|
|
560
848
|
// unwrap item from container
|
|
561
849
|
if (item instanceof TXmlElementController) {
|
|
@@ -564,6 +852,11 @@ class TXmlElementsListController {
|
|
|
564
852
|
return this._insItemRaw(index, item);
|
|
565
853
|
}
|
|
566
854
|
|
|
855
|
+
/**
|
|
856
|
+
* @param {index}
|
|
857
|
+
* @returns {bool}
|
|
858
|
+
* @description Deletes an element.
|
|
859
|
+
*/
|
|
567
860
|
delItem(value){
|
|
568
861
|
let isSUCCEED = this.chkIndex(value);
|
|
569
862
|
if (isSUCCEED) {
|
|
@@ -583,13 +876,18 @@ class TXmlElementsListController {
|
|
|
583
876
|
return isSUCCEED;
|
|
584
877
|
}
|
|
585
878
|
|
|
879
|
+
/**
|
|
880
|
+
* @param {any}
|
|
881
|
+
* @param {object} [opt]
|
|
882
|
+
* @param {bool} [opt.useClear=true]
|
|
883
|
+
* @returns {number}
|
|
884
|
+
* @description Loads a list of an elements.
|
|
885
|
+
*/
|
|
586
886
|
loadItems(items, opt){
|
|
587
887
|
const _options = isPlainObject(opt) ? opt : {};
|
|
588
888
|
let {
|
|
589
889
|
useClear,
|
|
590
|
-
load_as_new,
|
|
591
890
|
} = _options;
|
|
592
|
-
if (useClear === undefined) useClear = load_as_new;
|
|
593
891
|
if (typeof useClear !== 'boolean') useClear = true;
|
|
594
892
|
if (useClear) this.clear();
|
|
595
893
|
let count = this.count;
|
|
@@ -599,11 +897,21 @@ class TXmlElementsListController {
|
|
|
599
897
|
|
|
600
898
|
};
|
|
601
899
|
|
|
900
|
+
/**
|
|
901
|
+
* @description This class implements an instance of an element
|
|
902
|
+
* that managea content of a document declaration
|
|
903
|
+
*/
|
|
602
904
|
class TXmlContentDeclaration {
|
|
603
905
|
#_host = null;
|
|
604
906
|
#_options = null;
|
|
605
907
|
#_ctrls = null;
|
|
606
908
|
|
|
909
|
+
/**
|
|
910
|
+
* @param {object}
|
|
911
|
+
* @param {object} [opt]
|
|
912
|
+
* @param {object} [opt.parseOptions]
|
|
913
|
+
* @throws {TypeError}
|
|
914
|
+
*/
|
|
607
915
|
constructor(obj, opt){
|
|
608
916
|
// check <obj>-param
|
|
609
917
|
if (!isPlainObject(obj)) {
|
|
@@ -634,6 +942,9 @@ class TXmlContentDeclaration {
|
|
|
634
942
|
this.init();
|
|
635
943
|
}
|
|
636
944
|
|
|
945
|
+
/**
|
|
946
|
+
* @property {string}
|
|
947
|
+
*/
|
|
637
948
|
get version(){
|
|
638
949
|
return this.#_ctrls.getAttribute('version');
|
|
639
950
|
}
|
|
@@ -642,6 +953,9 @@ class TXmlContentDeclaration {
|
|
|
642
953
|
this.#_ctrls.setAttribute('version', value);
|
|
643
954
|
}
|
|
644
955
|
|
|
956
|
+
/**
|
|
957
|
+
* @property {string}
|
|
958
|
+
*/
|
|
645
959
|
get encoding(){
|
|
646
960
|
return this.#_ctrls.getAttribute('encoding');
|
|
647
961
|
}
|
|
@@ -650,6 +964,10 @@ class TXmlContentDeclaration {
|
|
|
650
964
|
this.#_ctrls.setAttribute('encoding', value);
|
|
651
965
|
}
|
|
652
966
|
|
|
967
|
+
/**
|
|
968
|
+
* @returns {bool}
|
|
969
|
+
* @description Initializes an instance content.
|
|
970
|
+
*/
|
|
653
971
|
init(){
|
|
654
972
|
const _options = this.#_options;
|
|
655
973
|
this.#_ctrls = new TXmlElementController(
|
|
@@ -666,10 +984,22 @@ class TXmlContentDeclaration {
|
|
|
666
984
|
|
|
667
985
|
};
|
|
668
986
|
|
|
987
|
+
/**
|
|
988
|
+
* @augments TXmlElementController
|
|
989
|
+
* @description This class implements an instance of a root element
|
|
990
|
+
*/
|
|
669
991
|
class TXmlContentRootElement extends TXmlElementController {
|
|
670
992
|
#_content = null;
|
|
671
993
|
#_options = null;
|
|
672
994
|
|
|
995
|
+
/**
|
|
996
|
+
* @param {object}
|
|
997
|
+
* @param {object} [opt]
|
|
998
|
+
* @param {object} [opt.parseOptions]
|
|
999
|
+
* @param {ID_STRING} [opt.rootETagName='']
|
|
1000
|
+
* @param {bool} [opt.autoBindRoot=true]
|
|
1001
|
+
* @throws {TypeError}
|
|
1002
|
+
*/
|
|
673
1003
|
constructor(obj, opt){
|
|
674
1004
|
// check <obj>-param
|
|
675
1005
|
if (!isPlainObject(obj)) {
|
|
@@ -755,17 +1085,28 @@ class TXmlContentRootElement extends TXmlElementController {
|
|
|
755
1085
|
//this.init(rootETagName);
|
|
756
1086
|
}
|
|
757
1087
|
|
|
1088
|
+
/**
|
|
1089
|
+
* @property {string}
|
|
1090
|
+
*/
|
|
758
1091
|
get tagName(){
|
|
759
1092
|
return this.#_options.rootETagName;
|
|
760
1093
|
}
|
|
761
1094
|
|
|
762
1095
|
set tagName(value){
|
|
763
|
-
value = readAsString(value,
|
|
1096
|
+
value = readAsString(value, true);
|
|
764
1097
|
this.#_options.rootETagName = isNotEmptyString(
|
|
765
1098
|
value
|
|
766
1099
|
) ? value : XML_DEF_ROOT_ETAG_NAME;
|
|
767
1100
|
}
|
|
768
1101
|
|
|
1102
|
+
/**
|
|
1103
|
+
* @param {object}
|
|
1104
|
+
* @param {bool} [opt=false]
|
|
1105
|
+
* @returns {?object}
|
|
1106
|
+
* @protected
|
|
1107
|
+
* @static
|
|
1108
|
+
* @description Tries to unwraps a given object.
|
|
1109
|
+
*/
|
|
769
1110
|
static __unwrap(item, opt){
|
|
770
1111
|
return (
|
|
771
1112
|
item instanceof TXmlContentRootElement
|
|
@@ -777,6 +1118,10 @@ class TXmlContentRootElement extends TXmlElementController {
|
|
|
777
1118
|
|
|
778
1119
|
}
|
|
779
1120
|
|
|
1121
|
+
/**
|
|
1122
|
+
* @description This class implements an instance of a container
|
|
1123
|
+
* that managea content of a document
|
|
1124
|
+
*/
|
|
780
1125
|
class TXmlContentContainer {
|
|
781
1126
|
#_content = null;
|
|
782
1127
|
#_options = null;
|
|
@@ -784,6 +1129,10 @@ class TXmlContentContainer {
|
|
|
784
1129
|
#_docDecl = null;
|
|
785
1130
|
#_docRoot = null;
|
|
786
1131
|
|
|
1132
|
+
/**
|
|
1133
|
+
* @param {object} [opt]
|
|
1134
|
+
* @param {object} [opt.parseOptions]
|
|
1135
|
+
*/
|
|
787
1136
|
constructor(opt){
|
|
788
1137
|
// load options
|
|
789
1138
|
const _options = isPlainObject(opt) ? opt : {};
|
|
@@ -805,15 +1154,29 @@ class TXmlContentContainer {
|
|
|
805
1154
|
this.#_docRoot = new TXmlContentRootElement(_content, _options);
|
|
806
1155
|
}
|
|
807
1156
|
|
|
1157
|
+
/**
|
|
1158
|
+
* @property {TXmlContentRootElement}
|
|
1159
|
+
* @readonly
|
|
1160
|
+
*/
|
|
808
1161
|
get rootElement(){
|
|
809
1162
|
return this.#_docRoot;
|
|
810
1163
|
}
|
|
811
1164
|
|
|
1165
|
+
/**
|
|
1166
|
+
* @returns {none}
|
|
1167
|
+
* @description Cleans a document content.
|
|
1168
|
+
*/
|
|
812
1169
|
clear(){
|
|
813
1170
|
this.#_docDecl.init();
|
|
814
1171
|
this.rootElement.clear();
|
|
815
1172
|
}
|
|
816
1173
|
|
|
1174
|
+
/**
|
|
1175
|
+
* @param {object}
|
|
1176
|
+
* @returns {bool}
|
|
1177
|
+
* @protected
|
|
1178
|
+
* @description Initializes an instance with a given content.
|
|
1179
|
+
*/
|
|
817
1180
|
_bindContent(obj, opt){
|
|
818
1181
|
const _options = isPlainObject(opt) ? opt : this.#_options;
|
|
819
1182
|
let isSUCCEED = false;
|
|
@@ -842,19 +1205,28 @@ class TXmlContentContainer {
|
|
|
842
1205
|
return isSUCCEED;
|
|
843
1206
|
}
|
|
844
1207
|
|
|
1208
|
+
/**
|
|
1209
|
+
* @returns {string}
|
|
1210
|
+
* @description Returns a document content as a string in an XML-format.
|
|
1211
|
+
*/
|
|
845
1212
|
saveToXMLString(){
|
|
846
1213
|
let result = '';
|
|
847
|
-
//let isERR = false;
|
|
848
1214
|
try {
|
|
849
1215
|
result = xmlParser.js2xml(this.#_content, this.#_parseOptions.js2xml);
|
|
850
1216
|
} catch (err) {
|
|
851
1217
|
//console.log('CHECK: TXmlContentContainer.saveToXMLString() => Error => '+err);
|
|
852
|
-
//isERR = true;
|
|
853
1218
|
throw err;
|
|
854
1219
|
};
|
|
855
1220
|
return result;
|
|
856
1221
|
}
|
|
857
1222
|
|
|
1223
|
+
/**
|
|
1224
|
+
* @param {string}
|
|
1225
|
+
* @returns {object}
|
|
1226
|
+
* @throws {Error}
|
|
1227
|
+
* @async
|
|
1228
|
+
* @description Saves a document content to a file.
|
|
1229
|
+
*/
|
|
858
1230
|
saveToFile(source){
|
|
859
1231
|
/**/// main part that return promise as a result
|
|
860
1232
|
return new Promise((resolve, reject) => {
|
|
@@ -878,26 +1250,26 @@ class TXmlContentContainer {
|
|
|
878
1250
|
data.errEvent = 'OPS_IS_SUCCEED';
|
|
879
1251
|
resolve(data);
|
|
880
1252
|
}).catch(err => {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
default: {
|
|
890
|
-
console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err);
|
|
891
|
-
console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err.code);
|
|
892
|
-
reject(err);
|
|
893
|
-
break;
|
|
894
|
-
}
|
|
1253
|
+
let { isSucceed } = checkFsError(data, err);
|
|
1254
|
+
if (isSucceed) {
|
|
1255
|
+
data.content = '';
|
|
1256
|
+
resolve(data);
|
|
1257
|
+
} else {
|
|
1258
|
+
//console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err);
|
|
1259
|
+
//console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err.code);
|
|
1260
|
+
reject(err);
|
|
895
1261
|
};
|
|
896
1262
|
});
|
|
897
1263
|
};
|
|
898
1264
|
});
|
|
899
1265
|
}
|
|
900
1266
|
|
|
1267
|
+
/**
|
|
1268
|
+
* @param {string}
|
|
1269
|
+
* @returns {object}
|
|
1270
|
+
* @throws {Error}
|
|
1271
|
+
* @description Saves a document content to a file.
|
|
1272
|
+
*/
|
|
901
1273
|
saveToFileSync(source){
|
|
902
1274
|
let data = {
|
|
903
1275
|
isSucceed: false,
|
|
@@ -916,25 +1288,25 @@ class TXmlContentContainer {
|
|
|
916
1288
|
data.content = this.saveToXMLString();
|
|
917
1289
|
fs.writeFileSync(data.source, data.content, 'utf8');
|
|
918
1290
|
} catch (err) {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
default: {
|
|
927
|
-
console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err);
|
|
928
|
-
console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err.code);
|
|
929
|
-
throw err;
|
|
930
|
-
break;
|
|
931
|
-
}
|
|
1291
|
+
let { isSucceed } = checkFsError(data, err);
|
|
1292
|
+
if (isSucceed) {
|
|
1293
|
+
data.content = '';
|
|
1294
|
+
} else {
|
|
1295
|
+
//console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err);
|
|
1296
|
+
//console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err.code);
|
|
1297
|
+
throw err;
|
|
932
1298
|
};
|
|
933
1299
|
};
|
|
934
1300
|
};
|
|
935
1301
|
return data;
|
|
936
1302
|
}
|
|
937
1303
|
|
|
1304
|
+
/**
|
|
1305
|
+
* @param {string}
|
|
1306
|
+
* @returns {bool}
|
|
1307
|
+
* @throws {Error}
|
|
1308
|
+
* @description Loads a document content from a string.
|
|
1309
|
+
*/
|
|
938
1310
|
loadFromXMLString(xmlString){
|
|
939
1311
|
let isSUCCEED = false;
|
|
940
1312
|
if (typeof xmlString === 'string') {
|
|
@@ -953,6 +1325,13 @@ class TXmlContentContainer {
|
|
|
953
1325
|
return isSUCCEED;
|
|
954
1326
|
}
|
|
955
1327
|
|
|
1328
|
+
/**
|
|
1329
|
+
* @param {string}
|
|
1330
|
+
* @returns {object}
|
|
1331
|
+
* @throws {Error}
|
|
1332
|
+
* @async
|
|
1333
|
+
* @description Loads a document content from a file.
|
|
1334
|
+
*/
|
|
956
1335
|
loadFromFile(source){
|
|
957
1336
|
/**/// main part that return promise as a result
|
|
958
1337
|
return new Promise((resolve, reject) => {
|
|
@@ -986,26 +1365,26 @@ class TXmlContentContainer {
|
|
|
986
1365
|
};
|
|
987
1366
|
resolve(data);
|
|
988
1367
|
}).catch(err => {
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
default: {
|
|
998
|
-
console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err);
|
|
999
|
-
console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err.code);
|
|
1000
|
-
reject(err);
|
|
1001
|
-
break;
|
|
1002
|
-
}
|
|
1368
|
+
let { isSucceed } = checkFsError(data, err);
|
|
1369
|
+
if (isSucceed) {
|
|
1370
|
+
data.content = '';
|
|
1371
|
+
resolve(data);
|
|
1372
|
+
} else {
|
|
1373
|
+
//console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err);
|
|
1374
|
+
//console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err.code);
|
|
1375
|
+
reject(err);
|
|
1003
1376
|
};
|
|
1004
1377
|
});
|
|
1005
1378
|
};
|
|
1006
1379
|
});
|
|
1007
1380
|
}
|
|
1008
1381
|
|
|
1382
|
+
/**
|
|
1383
|
+
* @param {string}
|
|
1384
|
+
* @returns {object}
|
|
1385
|
+
* @throws {Error}
|
|
1386
|
+
* @description Loads a document content from a file.
|
|
1387
|
+
*/
|
|
1009
1388
|
loadFromFileSync(source){
|
|
1010
1389
|
let data = {
|
|
1011
1390
|
isLoaded: false,
|
|
@@ -1035,25 +1414,24 @@ class TXmlContentContainer {
|
|
|
1035
1414
|
data.errEvent = 'NO_CONTENT';
|
|
1036
1415
|
};
|
|
1037
1416
|
} catch (err) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
default: {
|
|
1046
|
-
console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err);
|
|
1047
|
-
console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err.code);
|
|
1048
|
-
throw err;
|
|
1049
|
-
break;
|
|
1050
|
-
}
|
|
1417
|
+
let { isSucceed } = checkFsError(data, err);
|
|
1418
|
+
if (isSucceed) {
|
|
1419
|
+
data.content = '';
|
|
1420
|
+
} else {
|
|
1421
|
+
//console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err);
|
|
1422
|
+
//console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err.code);
|
|
1423
|
+
throw err;
|
|
1051
1424
|
};
|
|
1052
1425
|
};
|
|
1053
1426
|
};
|
|
1054
1427
|
return data;
|
|
1055
1428
|
}
|
|
1056
1429
|
|
|
1430
|
+
/**
|
|
1431
|
+
* @returns {string}
|
|
1432
|
+
* @protected
|
|
1433
|
+
* @description Returns a document content a string in a JSON-format.
|
|
1434
|
+
*/
|
|
1057
1435
|
asJSON(){
|
|
1058
1436
|
return JSON.stringify(this.#_content, null, 2);
|
|
1059
1437
|
}
|