@@ -310,7 +310,8 @@ const parseXml = function (xmlData) {
310310 if ( ch === '<' ) {
311311 // const nextIndex = i+1;
312312 // const _2ndChar = xmlData[nextIndex];
313- if ( xmlData [ i + 1 ] === '/' ) { //Closing Tag
313+ const c1 = xmlData . charCodeAt ( i + 1 ) ;
314+ if ( c1 === 47 ) { //Closing Tag '/'
314315 const closeIndex = findClosingIndex ( xmlData , ">" , i , "Closing Tag is not closed." )
315316 let tagName = xmlData . substring ( i + 2 , closeIndex ) . trim ( ) ;
316317
@@ -344,7 +345,7 @@ const parseXml = function (xmlData) {
344345 currentNode = this . tagsNodeStack . pop ( ) ; //avoid recursion, set the parent tag scope
345346 textData = "" ;
346347 i = closeIndex ;
347- } else if ( xmlData [ i + 1 ] === '?' ) {
348+ } else if ( c1 === 63 ) { //'?'
348349
349350 let tagData = readTagExp ( xmlData , i , false , "?>" ) ;
350351 if ( ! tagData ) throw new Error ( "Pi Tag is not closed." ) ;
@@ -365,7 +366,9 @@ const parseXml = function (xmlData) {
365366
366367
367368 i = tagData . closeIndex + 1 ;
368- } else if ( xmlData . substr ( i + 1 , 3 ) === '!--' ) {
369+ } else if ( c1 === 33
370+ && xmlData . charCodeAt ( i + 2 ) === 45
371+ && xmlData . charCodeAt ( i + 3 ) === 45 ) { //'!--'
369372 const endIndex = findClosingIndex ( xmlData , "-->" , i + 4 , "Comment is not closed." )
370373 if ( this . options . commentPropName ) {
371374 const comment = xmlData . substring ( i + 4 , endIndex - 2 ) ;
@@ -375,11 +378,13 @@ const parseXml = function (xmlData) {
375378 currentNode . add ( this . options . commentPropName , [ { [ this . options . textNodeName ] : comment } ] ) ;
376379 }
377380 i = endIndex ;
378- } else if ( xmlData . substr ( i + 1 , 2 ) === '!D' ) {
381+ } else if ( c1 === 33
382+ && xmlData . charCodeAt ( i + 2 ) === 68 ) { //'!D'
379383 const result = docTypeReader . readDocType ( xmlData , i ) ;
380384 this . docTypeEntities = result . entities ;
381385 i = result . i ;
382- } else if ( xmlData . substr ( i + 1 , 2 ) === '![' ) {
386+ } else if ( c1 === 33
387+ && xmlData . charCodeAt ( i + 2 ) === 91 ) { // '!['
383388 const closeIndex = findClosingIndex ( xmlData , "]]>" , i , "CDATA is not closed." ) - 2 ;
384389 const tagExp = xmlData . substring ( i + 9 , closeIndex ) ;
385390
@@ -735,32 +740,33 @@ function isItStopNode(stopNodeExpressions, matcher) {
735740 * @returns
736741 */
737742function tagExpWithClosingIndex ( xmlData , i , closingChar = ">" ) {
738- let attrBoundary ;
739- let tagExp = "" ;
740- for ( let index = i ; index < xmlData . length ; index ++ ) {
741- let ch = xmlData [ index ] ;
743+ let attrBoundary = 0 ;
744+ const chars = [ ] ;
745+ const len = xmlData . length ;
746+ const closeCode0 = closingChar . charCodeAt ( 0 ) ;
747+ const closeCode1 = closingChar . length > 1 ? closingChar . charCodeAt ( 1 ) : - 1 ;
748+
749+ for ( let index = i ; index < len ; index ++ ) {
750+ const code = xmlData . charCodeAt ( index ) ;
751+
742752 if ( attrBoundary ) {
743- if ( ch === attrBoundary ) attrBoundary = "" ; //reset
744- } else if ( ch === '"' || ch === "'" ) {
745- attrBoundary = ch ;
746- } else if ( ch === closingChar [ 0 ] ) {
747- if ( closingChar [ 1 ] ) {
748- if ( xmlData [ index + 1 ] === closingChar [ 1 ] ) {
749- return {
750- data : tagExp ,
751- index : index
752- }
753+ if ( code === attrBoundary ) attrBoundary = 0 ;
754+ } else if ( code === 34 || code === 39 ) { // " or '
755+ attrBoundary = code ;
756+ } else if ( code === closeCode0 ) {
757+ if ( closeCode1 !== - 1 ) {
758+ if ( xmlData . charCodeAt ( index + 1 ) === closeCode1 ) {
759+ return { data : String . fromCharCode ( ...chars ) , index } ;
753760 }
754761 } else {
755- return {
756- data : tagExp ,
757- index : index
758- }
762+ return { data : String . fromCharCode ( ...chars ) , index } ;
759763 }
760- } else if ( ch === '\t' ) {
761- ch = " "
764+ } else if ( code === 9 ) { // \t
765+ chars . push ( 32 ) ; // space
766+ continue ;
762767 }
763- tagExp += ch ;
768+
769+ chars . push ( code ) ;
764770 }
765771}
766772
@@ -816,7 +822,8 @@ function readStopNodeData(xmlData, tagName, i) {
816822
817823 for ( ; i < xmlData . length ; i ++ ) {
818824 if ( xmlData [ i ] === "<" ) {
819- if ( xmlData [ i + 1 ] === "/" ) { //close tag
825+ const c1 = xmlData . charCodeAt ( i + 1 ) ;
826+ if ( c1 === 47 ) { //close tag '/'
820827 const closeIndex = findClosingIndex ( xmlData , ">" , i , `${ tagName } is not closed` ) ;
821828 let closeTagName = xmlData . substring ( i + 2 , closeIndex ) . trim ( ) ;
822829 if ( closeTagName === tagName ) {
@@ -829,13 +836,16 @@ function readStopNodeData(xmlData, tagName, i) {
829836 }
830837 }
831838 i = closeIndex ;
832- } else if ( xmlData [ i + 1 ] === '?' ) {
839+ } else if ( c1 === 63 ) { //?
833840 const closeIndex = findClosingIndex ( xmlData , "?>" , i + 1 , "StopNode is not closed." )
834841 i = closeIndex ;
835- } else if ( xmlData . substr ( i + 1 , 3 ) === '!--' ) {
842+ } else if ( c1 === 33
843+ && xmlData . charCodeAt ( i + 2 ) === 45
844+ && xmlData . charCodeAt ( i + 3 ) === 45 ) { // '!--'
836845 const closeIndex = findClosingIndex ( xmlData , "-->" , i + 3 , "StopNode is not closed." )
837846 i = closeIndex ;
838- } else if ( xmlData . substr ( i + 1 , 2 ) === '![' ) {
847+ } else if ( c1 === 33
848+ && xmlData . charCodeAt ( i + 2 ) === 91 ) { // '!['
839849 const closeIndex = findClosingIndex ( xmlData , "]]>" , i , "StopNode is not closed." ) - 2 ;
840850 i = closeIndex ;
841851 } else {
0 commit comments