diff --git a/find-tag-by-name.js b/find-tag-by-name.js index d81a429..b3978cb 100644 --- a/find-tag-by-name.js +++ b/find-tag-by-name.js @@ -1,8 +1,10 @@ const indexOfMatch = require("./index-of-match.js"); const indexOfMatchEnd = require("./index-of-match-end.js"); +const countSubstring = require("./count-substring.js"); function findTagByName(xml, tagName, options) { const debug = (options && options.debug) || false; + const nested = !(options && typeof options.nested === false); const startIndex = (options && options.startIndex) || 0; @@ -20,7 +22,22 @@ function findTagByName(xml, tagName, options) { if (debug) console.log("[xml-utils] selfClosing:", selfClosing); if (selfClosing === false) { - relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", 0); + // check if tag has subtags with the same name + if (nested) { + let startIndex = 0; + let openings = 1; + let closings = 0; + while ((relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", startIndex)) !== -1) { + const clip = afterStart.substring(startIndex, relativeEnd + 1); + openings += countSubstring(clip, "<" + tagName); + closings += countSubstring(clip, "/" + tagName + ">"); + // we can't have more openings than closings + if (closings >= openings) break; + startIndex = relativeEnd; + } + } else { + relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", 0); + } } const end = start + tagName.length + relativeEnd + 1;