fast-xml-parser 4.0.8 → 4.0.9

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 CHANGED
@@ -1,6 +1,12 @@
1
1
  Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.
2
2
 
3
- **4.0.8 / 2022-03-18**
3
+ **4.0.9 / 2022-07-10**
4
+ * fix #470: stop-tag can have self-closing tag with same name
5
+ * fix #472: stopNode can have any special tag inside
6
+ * Allow !ATTLIST and !NOTATION with DOCTYPE
7
+ * Add transformTagName option to transform tag names when parsing (#469) (By [Erik Rothoff Andersson](https://github.com/erkie))
8
+
9
+ **4.0.8 / 2022-05-28**
4
10
  * Fix CDATA parsing returning empty string when value = 0 (#451) (By [ndelanou](https://github.com/ndelanou))
5
11
  * Fix stopNodes when same tag appears inside node (#456) (By [patrickshipe](https://github.com/patrickshipe))
6
12
  * fix #468: prettify own properties only
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fast-xml-parser",
3
- "version": "4.0.8",
3
+ "version": "4.0.9",
4
4
  "description": "Validate XML, Parse XML, Build XML without C/C++ based libraries",
5
5
  "main": "./src/fxp.js",
6
6
  "scripts": {
package/src/fxp.d.ts CHANGED
@@ -22,6 +22,7 @@ type X2jOptions = {
22
22
  htmlEntities: boolean;
23
23
  ignoreDeclaration: boolean;
24
24
  ignorePiTags: boolean;
25
+ transformTagName: ((tagName: string) => string) | false;
25
26
  };
26
27
  type strnumOptions = {
27
28
  hex: boolean;
@@ -30,7 +30,8 @@ const defaultOptions = {
30
30
  { regex: new RegExp("\"", "g"), val: """ }
31
31
  ],
32
32
  processEntities: true,
33
- stopNodes: []
33
+ stopNodes: [],
34
+ transformTagName: false,
34
35
  };
35
36
 
36
37
  function Builder(options) {
@@ -38,6 +38,31 @@ function readDocType(xmlData, i){
38
38
  ){
39
39
  //Not supported
40
40
  i += 8;
41
+ }else if( hasBody &&
42
+ xmlData[i+1] === '!' &&
43
+ xmlData[i+2] === 'A' &&
44
+ xmlData[i+3] === 'T' &&
45
+ xmlData[i+4] === 'T' &&
46
+ xmlData[i+5] === 'L' &&
47
+ xmlData[i+6] === 'I' &&
48
+ xmlData[i+7] === 'S' &&
49
+ xmlData[i+8] === 'T'
50
+ ){
51
+ //Not supported
52
+ i += 8;
53
+ }else if( hasBody &&
54
+ xmlData[i+1] === '!' &&
55
+ xmlData[i+2] === 'N' &&
56
+ xmlData[i+3] === 'O' &&
57
+ xmlData[i+4] === 'T' &&
58
+ xmlData[i+5] === 'A' &&
59
+ xmlData[i+6] === 'T' &&
60
+ xmlData[i+7] === 'I' &&
61
+ xmlData[i+8] === 'O' &&
62
+ xmlData[i+9] === 'N'
63
+ ){
64
+ //Not supported
65
+ i += 9;
41
66
  }else if( //comment
42
67
  xmlData[i+1] === '!' &&
43
68
  xmlData[i+2] === '-' &&
@@ -30,7 +30,8 @@ const defaultOptions = {
30
30
  processEntities: true,
31
31
  htmlEntities: false,
32
32
  ignoreDeclaration: false,
33
- ignorePiTags: false
33
+ ignorePiTags: false,
34
+ transformTagName: false,
34
35
  };
35
36
 
36
37
  const buildOptions = function(options) {
@@ -193,6 +193,10 @@ const parseXml = function(xmlData) {
193
193
  }
194
194
  }
195
195
 
196
+ if(this.options.transformTagName) {
197
+ tagName = this.options.transformTagName(tagName);
198
+ }
199
+
196
200
  if(currentNode){
197
201
  textData = this.saveTextToParentTag(textData, currentNode, jPath);
198
202
  }
@@ -257,12 +261,15 @@ const parseXml = function(xmlData) {
257
261
 
258
262
  i = closeIndex + 2;
259
263
  }else {//Opening tag
260
-
261
264
  let result = readTagExp(xmlData,i, this. options.removeNSPrefix);
262
265
  let tagName= result.tagName;
263
266
  let tagExp = result.tagExp;
264
267
  let attrExpPresent = result.attrExpPresent;
265
268
  let closeIndex = result.closeIndex;
269
+
270
+ if (this.options.transformTagName) {
271
+ tagName = this.options.transformTagName(tagName);
272
+ }
266
273
 
267
274
  //save text as child node
268
275
  if (currentNode && textData) {
@@ -322,6 +329,10 @@ const parseXml = function(xmlData) {
322
329
  }else{
323
330
  tagExp = tagExp.substr(0, tagExp.length - 1);
324
331
  }
332
+
333
+ if(this.options.transformTagName) {
334
+ tagName = this.options.transformTagName(tagName);
335
+ }
325
336
 
326
337
  const childNode = new xmlNode(tagName);
327
338
  if(tagName !== tagExp && attrExpPresent){
@@ -491,7 +502,7 @@ function readStopNodeData(xmlData, tagName, i){
491
502
 
492
503
  for (; i < xmlData.length; i++) {
493
504
  if( xmlData[i] === "<"){
494
- if (xmlData[i+1] === "/") {
505
+ if (xmlData[i+1] === "/") {//close tag
495
506
  const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`);
496
507
  let closeTagName = xmlData.substring(i+2,closeIndex).trim();
497
508
  if(closeTagName === tagName){
@@ -504,12 +515,21 @@ function readStopNodeData(xmlData, tagName, i){
504
515
  }
505
516
  }
506
517
  i=closeIndex;
518
+ } else if(xmlData[i+1] === '?') {
519
+ const closeIndex = findClosingIndex(xmlData, "?>", i+1, "StopNode is not closed.")
520
+ i=closeIndex;
521
+ } else if(xmlData.substr(i + 1, 3) === '!--') {
522
+ const closeIndex = findClosingIndex(xmlData, "-->", i+3, "StopNode is not closed.")
523
+ i=closeIndex;
524
+ } else if(xmlData.substr(i + 1, 2) === '![') {
525
+ const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
526
+ i=closeIndex;
507
527
  } else {
508
528
  const tagData = readTagExp(xmlData, i, '>')
509
529
 
510
530
  if (tagData) {
511
531
  const openTagName = tagData && tagData.tagName;
512
- if (openTagName === tagName) {
532
+ if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") {
513
533
  openTagCount++;
514
534
  }
515
535
  i=tagData.closeIndex;