diff --git a/spec/stopNodes_spec.js b/spec/stopNodes_spec.js
new file mode 100644
index 00000000..c36fdf31
--- /dev/null
+++ b/spec/stopNodes_spec.js
@@ -0,0 +1,187 @@
+"use strict";
+
+const parser = require("../src/parser");
+const validator = require("../src/validator");
+const he = require("he");
+
+describe("XMLParser", 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
"
+ }
+ };
+
+ let result = parser.parse(xmlData, {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["fix1"]
+ });
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = validator.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
"
+ }
+ };
+
+ let result = parser.parse(xmlData, {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["fix1", "fix2"]
+ });
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = validator.validate(xmlData);
+ expect(result).toBe(true);
+ });
+
+ it("1c. have two stopNodes, one within the other", function() {
+ const xmlData = `test 1p 1
p 2
div 2
div 1
`;
+ const expected = {
+ "issue": {
+ "title": "test 1",
+ "fix1": {
+ "#text": "p 1
p 2
div 2
div 1
",
+ "lang": "en"
+ }
+ }
+ };
+
+ let result = parser.parse(xmlData, {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["fix1", "fix2"]
+ });
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = validator.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": ""
+ }
+ };
+
+ let result = parser.parse(xmlData, {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["fix1", "fix2"]
+ });
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = validator.validate(xmlData);
+ expect(result).toBe(true);
+ });
+
+ it("2b. stop node is self-closing", function() {
+ const xmlData = `test 1`;
+ const expected = {
+ "issue": {
+ "title": "test 1",
+ "fix1": ""
+ }
+ };
+
+ let result = parser.parse(xmlData, {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["fix1", "fix2"]
+ });
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = validator.validate(xmlData);
+ expect(result).toBe(true);
+ });
+
+ it("4. cdata", function() {
+ const xmlData = `
+
+
+ +122233344550
+ Jack]]>
+ Mohan]]>
+
+
+
+
+ Mohan]]>
+
+`;
+ const expected = {
+ "issue": {
+ "fix1": "\n +122233344550\n Jack]]>\n Mohan]]>\n \n \n ",
+ "fix2": "\n\t\tMohan]]>\n\t"
+ }
+ };
+
+ let result = parser.parse(xmlData, {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ parseAttributeValue: true,
+ stopNodes: ["fix1", "fix2"]
+ });
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = validator.validate(xmlData, {
+ allowBooleanAttributes: true
+ });
+ expect(result).toBe(true);
+ });
+
+ it("5. stopNode at root level", function() {
+ const xmlData = `p 1
div 1
`;
+ const expected = {
+ "fix1": "p 1
div 1
"
+ };
+
+ let result = parser.parse(xmlData, {
+ attributeNamePrefix: "",
+ ignoreAttributes: false,
+ stopNodes: ["fix1", "fix2"]
+ });
+
+ //console.log(JSON.stringify(result,null,4));
+ expect(result).toEqual(expected);
+
+ result = validator.validate(xmlData, {
+ allowBooleanAttributes: true
+ });
+ expect(result).toBe(true);
+ });
+});
diff --git a/src/xmlstr2xmlnode.js b/src/xmlstr2xmlnode.js
index 16122ee6..c8e5b83b 100644
--- a/src/xmlstr2xmlnode.js
+++ b/src/xmlstr2xmlnode.js
@@ -39,6 +39,7 @@ const defaultOptions = {
attrValueProcessor: function(a) {
return a;
},
+ stopNodes: []
//decodeStrict: false,
};
@@ -61,6 +62,7 @@ const props = [
'tagValueProcessor',
'attrValueProcessor',
'parseTrueNumberOnly',
+ 'stopNodes'
];
exports.props = props;
@@ -84,7 +86,11 @@ const getTraversalObj = function(xmlData, options) {
if (currentNode.parent && tag[14]) {
currentNode.parent.val = util.getValue(currentNode.parent.val) + '' + processTagValue(tag[14], options);
}
-
+ if (options.stopNodes.length && options.stopNodes.includes(currentNode.tagname)) {
+ currentNode.child = []
+ if (currentNode.attrsMap == undefined) { currentNode.attrsMap = {}}
+ currentNode.val = xmlData.substr(currentNode.startIndex + 1, tag.index - currentNode.startIndex - 1)
+ }
currentNode = currentNode.parent;
} else if (tagType === TagType.CDATA) {
if (options.cdataTagName) {
@@ -119,6 +125,9 @@ const getTraversalObj = function(xmlData, options) {
currentNode,
processTagValue(tag[14], options)
);
+ if (options.stopNodes.length && options.stopNodes.includes(childNode.tagname)) {
+ childNode.startIndex=tag.index + tag[1].length
+ }
childNode.attrsMap = buildAttributesMap(tag[8], options);
currentNode.addChild(childNode);
currentNode = childNode;