diff --git a/spec/stopNodes_spec.js b/spec/stopNodes_spec.js
index 25f0d6b5..afefa5b5 100644
--- a/spec/stopNodes_spec.js
+++ b/spec/stopNodes_spec.js
@@ -1,64 +1,64 @@
"use strict";
-const {XMLParser, XMLValidator} = require("../src/fxp");
+const { XMLParser, XMLValidator } = require("../src/fxp");
const he = require("he");
-describe("XMLParser StopNodes", function() {
- it("1a. should support single stopNode", function() {
- const xmlData = `test 1p 1
div 1
`;
- const expected = {
- "issue": {
- "title": "test 1",
- "fix1": "
p 1
div 1
"
- }
- };
-
- const options = {
- attributeNamePrefix: "",
- ignoreAttributes: false,
- parseAttributeValue: true,
- stopNodes: ["issue.fix1"]
- };
- const parser = new XMLParser(options);
- let result = parser.parse(xmlData);
-
- // console.log(JSON.stringify(result,null,4));
- expect(result).toEqual(expected);
-
- result = XMLValidator.validate(xmlData);
- expect(result).toBe(true);
- });
+describe("XMLParser StopNodes", function () {
+ it("1a. should support single stopNode", function () {
+ const xmlData = `test 1p 1
div 1
`;
+ const expected = {
+ "issue": {
+ "title": "test 1",
+ "fix1": "p 1
div 1
"
+ }
+ };
- it("1b. 3. should support more than one stopNodes, with or without attr", function() {
- const xmlData = `test 1p 1
div 1
p 2
div 2
`;
- const expected = {
- "issue": {
- "title": "test 1",
- "fix1": {
- "#text": "p 1
div 1
",
- "lang": "en"
- },
- "fix2": "p 2
div 2
"
- }
- };
-
- const options = {
- attributeNamePrefix: "",
- ignoreAttributes: false,
- parseAttributeValue: true,
- stopNodes: ["issue.fix1", "issue.fix2"]
- };
- const parser = new XMLParser(options);
- let result = parser.parse(xmlData);
-
- // console.log(JSON.stringify(result,null,4));
- expect(result).toEqual(expected);
-
- result = XMLValidator.validate(xmlData);
- expect(result).toBe(true);
- });
+ const options = {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["issue.fix1"]
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(xmlData);
+
+ // console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = XMLValidator.validate(xmlData);
+ expect(result).toBe(true);
+ });
+
+ it("1b. 3. should support more than one stopNodes, with or without attr", function () {
+ const xmlData = `test 1p 1
div 1
p 2
div 2
`;
+ const expected = {
+ "issue": {
+ "title": "test 1",
+ "fix1": {
+ "#text": "p 1
div 1
",
+ "lang": "en"
+ },
+ "fix2": "p 2
div 2
"
+ }
+ };
+
+ const options = {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["issue.fix1", "issue.fix2"]
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(xmlData);
+
+ // console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = XMLValidator.validate(xmlData);
+ expect(result).toBe(true);
+ });
- it("1c. have two stopNodes, one within the other", function() {
+ it("1c. have two stopNodes, one within the other", function () {
const xmlData = `test 1p 1
p 2
div 2
div 1
`;
const expected = {
"issue": {
@@ -72,12 +72,12 @@ describe("XMLParser StopNodes", function() {
const options = {
attributeNamePrefix: "",
- ignoreAttributes: false,
- parseAttributeValue: true,
- stopNodes: ["issue.fix1", "issue.fix2"]
- };
- const parser = new XMLParser(options);
- let result = parser.parse(xmlData);
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["issue.fix1", "issue.fix2"]
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(xmlData);
//console.log(JSON.stringify(result,null,4));
expect(result).toEqual(expected);
@@ -86,81 +86,81 @@ describe("XMLParser StopNodes", function() {
expect(result).toBe(true);
});
- it("2a. stop node has nothing in it", function() {
- const xmlData = `test 1`;
- const expected = {
- "issue": {
- "title": "test 1",
- "fix1": ""
- }
- };
-
- const options = {
- attributeNamePrefix: "",
- ignoreAttributes: false,
- parseAttributeValue: true,
- stopNodes: ["issue.fix1", "issue.fix2"]
- };
- const parser = new XMLParser(options);
- let result = parser.parse(xmlData);
-
- //console.log(JSON.stringify(result,null,4));
- expect(result).toEqual(expected);
-
- result = XMLValidator.validate(xmlData);
- expect(result).toBe(true);
- });
+ it("2a. stop node has nothing in it", function () {
+ const xmlData = `test 1`;
+ const expected = {
+ "issue": {
+ "title": "test 1",
+ "fix1": ""
+ }
+ };
- it("2b. stop node is self-closing", function() {
- const xmlData = `test 1`;
- const expected = {
- "issue": {
- "title": "test 1",
- "fix1": ""
- }
- };
+ const options = {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["issue.fix1", "issue.fix2"]
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(xmlData);
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = XMLValidator.validate(xmlData);
+ expect(result).toBe(true);
+ });
- const options = {
- attributeNamePrefix: "",
- ignoreAttributes: false,
- parseAttributeValue: true,
- stopNodes: ["issue.fix1", "issue.fix2"]
+ it("2b. stop node is self-closing", function () {
+ const xmlData = `test 1`;
+ const expected = {
+ "issue": {
+ "title": "test 1",
+ "fix1": ""
+ }
+ };
+
+ const options = {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["issue.fix1", "issue.fix2"]
};
const parser = new XMLParser(options);
let result = parser.parse(xmlData);
- //console.log(JSON.stringify(result,null,4));
- expect(result).toEqual(expected);
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
- result = XMLValidator.validate(xmlData);
- expect(result).toBe(true);
- });
+ result = XMLValidator.validate(xmlData);
+ expect(result).toBe(true);
+ });
+
+ it("5. stopNode at root level", function () {
+ const xmlData = `p 1
div 1
`;
+ const expected = {
+ "fix1": "p 1
div 1
"
+ };
+
+ const options = {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ stopNodes: ["fix1", "fix2"]
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(xmlData);
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
- it("5. stopNode at root level", function() {
- const xmlData = `p 1
div 1
`;
- const expected = {
- "fix1": "p 1
div 1
"
- };
-
- const options = {
- attributeNamePrefix: "",
- ignoreAttributes: false,
- stopNodes: ["fix1", "fix2"]
- };
- const parser = new XMLParser(options);
- let result = parser.parse(xmlData);
-
- //console.log(JSON.stringify(result,null,4));
- expect(result).toEqual(expected);
-
- result = XMLValidator.validate(xmlData, {
- allowBooleanAttributes: true
- });
- expect(result).toBe(true);
+ result = XMLValidator.validate(xmlData, {
+ allowBooleanAttributes: true
});
-
- it("should skip all nodes of given name irrespective of their level", function() {
- const xmlData = `
+ expect(result).toBe(true);
+ });
+
+ it("should skip all nodes of given name irrespective of their level", function () {
+ const xmlData = `
p 1
@@ -172,34 +172,34 @@ describe("XMLParser StopNodes", function() {
`;
- const expected = {
- "root": {
- "fix1": "\n p 1
\n div 1
\n ",
- "another": {
- "fix1": "\n str\n "
- }
- }
- };
-
- const options = {
- attributeNamePrefix: "",
- ignoreAttributes: false,
- stopNodes: ["*.fix1", "fix2"]
- };
- const parser = new XMLParser(options);
- let result = parser.parse(xmlData);
-
- // console.log(JSON.stringify(result,null,4));
- expect(result).toEqual(expected);
-
- result = XMLValidator.validate(xmlData, {
- allowBooleanAttributes: true
- });
- expect(result).toBe(true);
+ const expected = {
+ "root": {
+ "fix1": "\n p 1
\n div 1
\n ",
+ "another": {
+ "fix1": "\n str\n "
+ }
+ }
+ };
+
+ const options = {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ stopNodes: ["*.fix1", "fix2"]
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(xmlData);
+
+ // console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = XMLValidator.validate(xmlData, {
+ allowBooleanAttributes: true
});
+ expect(result).toBe(true);
+ });
- it("should call tagValueProcessor for stop Node", function() {
- const XMLdata = `
+ it("should call tagValueProcessor for stop Node", function () {
+ const XMLdata = `
@@ -217,108 +217,150 @@ describe("XMLParser StopNodes", function() {
`;
-
- const expected = {
- "products": {
- "script": "",
- "product": {
- "pid": "8",
- "modelno": "6273033",
- "name": " Big Red Truck ",
- "category": " Toys",
- "currency": "USD",
- "price": "19.20"
- }
- }
- };
-
- const options = {
- ignoreAttributes: true,
- stopNodes: [
- "products.product.price"
- ],
- tagValueProcessor: (tagName, tagValue, jPath, hasAttributes, isLeafNode) => {
- if(jPath === 'products.product.price'){
- // console.log(tagName, tagValue, jPath, hasAttributes, isLeafNode);
- return /([0-9]+\.[0-9]+)/.exec(tagValue)[1]
- }
- },
- // preserveOrder: true,
- };
- const parser = new XMLParser(options);
- let result = parser.parse(XMLdata);
- // console.log(JSON.stringify(result, null,4));
-
- expect(expected).toEqual(result);
+
+ const expected = {
+ "products": {
+ "script": "",
+ "product": {
+ "pid": "8",
+ "modelno": "6273033",
+ "name": " Big Red Truck ",
+ "category": " Toys",
+ "currency": "USD",
+ "price": "19.20"
+ }
+ }
+ };
+
+ const options = {
+ ignoreAttributes: true,
+ stopNodes: [
+ "products.product.price"
+ ],
+ tagValueProcessor: (tagName, tagValue, jPath, hasAttributes, isLeafNode) => {
+ if (jPath === 'products.product.price') {
+ // console.log(tagName, tagValue, jPath, hasAttributes, isLeafNode);
+ return /([0-9]+\.[0-9]+)/.exec(tagValue)[1]
+ }
+ },
+ // preserveOrder: true,
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(XMLdata);
+ // console.log(JSON.stringify(result, null,4));
+
+ expect(expected).toEqual(result);
});
- it("should skip self-closing stop nodes", function() {
- const XMLdata = ``;
-
- const expected = [{
- root: [
- { foo: [ { '#text': '' } ] },
- { bar: [ { '#text': '' } ] }
- ]
- }];
-
- const options = {
- // ignoreAttributes: true,
- stopNodes: ["*.foo", "*.bar"],
- preserveOrder: true,
- };
- const parser = new XMLParser(options);
- let result = parser.parse(XMLdata);
- // console.log(JSON.stringify(result, null,4));
-
- expect(expected).toEqual(result);
+ it("should skip self-closing stop nodes", function () {
+ const XMLdata = ``;
+
+ const expected = [{
+ root: [
+ { foo: [{ '#text': '' }] },
+ { bar: [{ '#text': '' }] }
+ ]
+ }];
+
+ const options = {
+ // ignoreAttributes: true,
+ stopNodes: ["*.foo", "*.bar"],
+ preserveOrder: true,
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(XMLdata);
+ // console.log(JSON.stringify(result, null,4));
+
+ expect(expected).toEqual(result);
});
- it("should skip unpaired stop nodes", function() {
- const XMLdata = ``;
-
- const expected = [{
- root: [
- { foo: [ { '#text': '' } ] },
- { bar: [ { '#text': '' } ] }
- ]
- }];
-
- const options = {
- // ignoreAttributes: true,
- stopNodes: ["*.foo", "*.bar"],
- unpairedTags: ["bar"],
- preserveOrder: true,
- };
- const parser = new XMLParser(options);
- let result = parser.parse(XMLdata);
- // console.log(JSON.stringify(result, null,4));
-
- expect(expected).toEqual(result);
+ it("should skip unpaired stop nodes", function () {
+ const XMLdata = ``;
+
+ const expected = [{
+ root: [
+ { foo: [{ '#text': '' }] },
+ { bar: [{ '#text': '' }] }
+ ]
+ }];
+
+ const options = {
+ // ignoreAttributes: true,
+ stopNodes: ["*.foo", "*.bar"],
+ unpairedTags: ["bar"],
+ preserveOrder: true,
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(XMLdata);
+ // console.log(JSON.stringify(result, null,4));
+
+ expect(expected).toEqual(result);
});
- it("should not incorrectly close the stop node if the same tag name appears inside", function() {
- const xmlData = `test 1p 1
div 1
moresomething`;
- const expected = {
- issue: {
- title: 'test 1',
- fix1: 'p 1
div 1
more',
- last: 'something'
- },
- };
-
- const options = {
- attributeNamePrefix: "",
- ignoreAttributes: false,
- parseAttributeValue: true,
- stopNodes: ["issue.fix1"]
- };
- const parser = new XMLParser(options);
- let result = parser.parse(xmlData);
-
- // console.log(JSON.stringify(result,null,4));
- expect(result).toEqual(expected);
-
- result = XMLValidator.validate(xmlData);
- expect(result).toBe(true);
+ it("should not incorrectly close the stop node if the same tag name appears inside", function () {
+ const xmlData = `test 1p 1
div 1
moresomething`;
+ const expected = {
+ issue: {
+ title: 'test 1',
+ fix1: 'p 1
div 1
more',
+ last: 'something'
+ },
+ };
+
+ const options = {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["issue.fix1"]
+ };
+ const parser = new XMLParser(options);
+ let result = parser.parse(xmlData);
+
+ // console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = XMLValidator.validate(xmlData);
+ expect(result).toBe(true);
+ });
+ it("should allow CDATA, comment or any other special tag inside", function () {
+ const xmldata = `'`;
+
+ const stopNodes = [
+ '*.b',
+ ];
+
+ const options = {
+ stopNodes,
+ };
+ const expected = {
+ "a": {
+ "b": [
+ "",
+ "'"
+ ]
+ }
+ };
+ const parser = new XMLParser(options);
+ let jObj = parser.parse(xmldata);
+ // console.log(JSON.stringify(jObj,null,4));
+ expect(jObj).toEqual(expected);
+ });
+
+ it("should allow self closing tag with same tag-name", function () {
+ const xmldata = ``;
+ const expected = {
+ "b": ""
+ };
+ const stopNodes = [
+ '*.b',
+ ];
+
+ const options = {
+ stopNodes,
+ };
+
+ const parser = new XMLParser(options);
+ let jObj = parser.parse(xmldata);
+ // console.log(JSON.stringify(jObj, null, 4));
+ expect(jObj).toEqual(expected);
});
});
diff --git a/src/xmlparser/OrderedObjParser.js b/src/xmlparser/OrderedObjParser.js
index 82f6c403..d2f79eca 100644
--- a/src/xmlparser/OrderedObjParser.js
+++ b/src/xmlparser/OrderedObjParser.js
@@ -502,7 +502,7 @@ function readStopNodeData(xmlData, tagName, i){
for (; i < xmlData.length; i++) {
if( xmlData[i] === "<"){
- if (xmlData[i+1] === "/") {
+ if (xmlData[i+1] === "/") {//close tag
const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`);
let closeTagName = xmlData.substring(i+2,closeIndex).trim();
if(closeTagName === tagName){
@@ -515,6 +515,15 @@ function readStopNodeData(xmlData, tagName, i){
}
}
i=closeIndex;
+ } else if(xmlData[i+1] === '?') {
+ const closeIndex = findClosingIndex(xmlData, "?>", i+1, "StopNode is not closed.")
+ i=closeIndex;
+ } else if(xmlData.substr(i + 1, 3) === '!--') {
+ const closeIndex = findClosingIndex(xmlData, "-->", i+3, "StopNode is not closed.")
+ i=closeIndex;
+ } else if(xmlData.substr(i + 1, 2) === '![') {
+ const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
+ i=closeIndex;
} else {
const tagData = readTagExp(xmlData, i, '>')