@@ -383,7 +383,7 @@ function Parser(options){
383383 }
384384
385385 if ( this . options . format ) {
386- this . indentate = indentate ;
386+ this . indentate = indentate ;
387387 this . tagEndChar = ">\n" ;
388388 this . newLine = "\n" ;
389389 } else {
@@ -416,7 +416,9 @@ Parser.prototype.j2x = function(jObj,level){
416416 var len = keys . length ;
417417 for ( var i = 0 ; i < len ; i ++ ) {
418418 var key = keys [ i ] ;
419- if ( typeof jObj [ key ] !== "object" ) { //premitive type
419+ if ( typeof jObj [ key ] === "undefined" ) {
420+ // supress undefined node
421+ } else if ( typeof jObj [ key ] !== "object" ) { //premitive type
420422 var attr = this . isAttribute ( key ) ;
421423 if ( attr ) {
422424 attrStr += " " + attr + "=\"" + this . encodeHTMLchar ( jObj [ key ] , true ) + "\"" ;
@@ -431,7 +433,7 @@ Parser.prototype.j2x = function(jObj,level){
431433 if ( jObj [ this . options . cdataTagName ] ) {
432434 //value will added while processing cdata
433435 } else {
434- val += this . encodeHTMLchar ( jObj [ key ] ) ;
436+ val += this . encodeHTMLchar ( jObj [ key ] ) ;
435437 }
436438 } else {
437439 val += this . buildTextNode ( jObj [ key ] , key , "" , level ) ;
@@ -448,7 +450,9 @@ Parser.prototype.j2x = function(jObj,level){
448450 var arrLen = jObj [ key ] . length ;
449451 for ( var j = 0 ; j < arrLen ; j ++ ) {
450452 var item = jObj [ key ] [ j ] ;
451- if ( typeof item === "object" ) {
453+ if ( typeof item === "undefined" ) {
454+ // supress undefined node
455+ } else if ( typeof item === "object" ) {
452456 var result = this . j2x ( item , level + 1 ) ;
453457 val += this . buildObjNode ( result . val , key , result . attrStr , level ) ;
454458 } else {
@@ -457,7 +461,7 @@ Parser.prototype.j2x = function(jObj,level){
457461 }
458462 }
459463 } else {
460-
464+
461465 if ( this . options . attrNodeName && key === this . options . attrNodeName ) {
462466 var Ks = Object . keys ( jObj [ key ] ) ;
463467 var L = Ks . length ;
@@ -495,10 +499,10 @@ function replaceCDATAarr(str,cdata){
495499}
496500
497501function buildObjectNode ( val , key , attrStr , level ) {
498- return this . indentate ( level )
499- + "<" + key + attrStr
500- + this . tagEndChar
501- + val
502+ return this . indentate ( level )
503+ + "<" + key + attrStr
504+ + this . tagEndChar
505+ + val
502506 //+ this.newLine
503507 + this . indentate ( level )
504508 + "</" + key + this . tagEndChar ;
@@ -508,10 +512,10 @@ function buildEmptyObjNode(val,key,attrStr,level){
508512 if ( val !== "" ) {
509513 return this . buildObjectNode ( val , key , attrStr , level ) ;
510514 } else {
511- return this . indentate ( level )
512- + "<" + key + attrStr
515+ return this . indentate ( level )
516+ + "<" + key + attrStr
513517 + "/"
514- + this . tagEndChar
518+ + this . tagEndChar
515519 //+ this.newLine
516520 }
517521}
@@ -556,14 +560,160 @@ function isCDATA(name){
556560
557561
558562module . exports = Parser ;
563+
559564} , { "he" :1 } ] , 3 :[ function ( require , module , exports ) {
565+ var char = function ( a ) {
566+ return String . fromCharCode ( a ) ;
567+ }
568+
569+ var defaultOptions = {
570+ attributeNamePrefix : "@_" ,
571+ attrNodeName : false ,
572+ textNodeName : "#text" ,
573+ ignoreAttributes : true ,
574+ ignoreNameSpace : false ,
575+ allowBooleanAttributes : false , //a tag can have attributes without any value
576+ //ignoreRootElement : false,
577+ parseNodeValue : true ,
578+ parseAttributeValue : false ,
579+ arrayMode : false ,
580+ trimValues : true , //Trim string values of tag and attributes
581+ decodeHTMLchar : false ,
582+ cdataTagName : false ,
583+ cdataPositionChar : "\\c"
584+ //decodeStrict: false,
585+ } ;
586+
587+ const chars = {
588+ nilChar : char ( 254 ) ,
589+ missingChar : char ( 200 ) ,
590+ nilPremitive : char ( 176 ) ,
591+ missingPremitive : char ( 201 ) ,
592+ emptyChar : char ( 177 ) ,
593+ emptyValue : char ( 178 ) ,
594+ boundryChar : char ( 186 ) ,
595+ arrayEnd : char ( 197 ) ,
596+ objStart : char ( 198 ) ,
597+ arrStart : char ( 199 )
598+ } ;
599+
600+
601+ const charsArr = [
602+ chars . nilChar ,
603+ chars . nilPremitive ,
604+ chars . missingChar ,
605+ chars . missingPremitive ,
606+ chars . boundryChar ,
607+ chars . emptyChar ,
608+ chars . arrayEnd ,
609+ chars . objStart ,
610+ chars . arrStart
611+ ]
612+
613+
614+ var _e = function ( node , e_schema , options ) {
615+ if ( typeof e_schema === "string" ) { //premitive
616+ if ( node && node [ 0 ] && node [ 0 ] . val !== undefined ) {
617+ return getValue ( node [ 0 ] . val , e_schema ) ;
618+ } else {
619+ return getValue ( node , e_schema ) ;
620+ }
621+ } else {
622+ var hasValidData = hasData ( node ) ;
623+ if ( hasValidData === true ) {
624+ var str = "" ;
625+ if ( Array . isArray ( e_schema ) ) {
626+ //attributes can't be repeated. hence check in children tags only
627+ str += chars . arrStart ;
628+ var itemSchema = e_schema [ 0 ] ;
629+ //var itemSchemaType = itemSchema;
630+ var arr_len = node . length ;
631+
632+ if ( typeof itemSchema === "string" ) {
633+ for ( var arr_i = 0 ; arr_i < arr_len ; arr_i ++ ) {
634+ var r = getValue ( node [ arr_i ] . val , itemSchema ) ;
635+ str = processValue ( str , r ) ;
636+ }
637+ } else {
638+ for ( var arr_i = 0 ; arr_i < arr_len ; arr_i ++ ) {
639+ r = _e ( node [ arr_i ] , itemSchema , options ) ;
640+ str = processValue ( str , r ) ;
641+ }
642+ }
643+ str += chars . arrayEnd ; //indicates that next item is not array item
644+ } else { //object
645+ str += chars . objStart ;
646+ var keys = Object . keys ( e_schema ) ;
647+ if ( Array . isArray ( node ) ) node = node [ 0 ] ;
648+ for ( var i in keys ) {
649+ var key = keys [ i ] ;
650+ //a property defined in schema can be present either in attrsMap or children tags
651+ //options.textNodeName will not present in both maps, take it's value from val
652+ //options.attrNodeName will be present in attrsMap
653+ var r ;
654+ if ( ! options . ignoreAttributes && node . attrsMap && node . attrsMap [ key ] ) {
655+ r = _e ( node . attrsMap [ key ] , e_schema [ key ] , options ) ;
656+ } else if ( key === options . textNodeName ) {
657+ r = _e ( node . val , e_schema [ key ] , options ) ;
658+ } else {
659+ r = _e ( node . child [ key ] , e_schema [ key ] , options ) ;
660+ }
661+ str = processValue ( str , r ) ;
662+ }
663+ }
664+ return str ;
665+ } else {
666+ return hasValidData ;
667+ }
668+ }
669+ }
670+
671+ var getValue = function ( a , type ) {
672+ switch ( a ) {
673+ case undefined : return chars . missingPremitive ;
674+ case null : return chars . nilPremitive ;
675+ case "" : return chars . emptyValue ;
676+ default : return a ;
677+ }
678+ }
679+
680+ var processValue = function ( str , r ) {
681+ if ( ! isAppChar ( r [ 0 ] ) && ! isAppChar ( str [ str . length - 1 ] ) ) {
682+ str += chars . boundryChar ;
683+ }
684+ return str + r ;
685+ }
686+
687+ var isAppChar = function ( ch ) {
688+ return charsArr . indexOf ( ch ) !== - 1 ;
689+ }
690+
691+ function hasData ( jObj ) {
692+ if ( jObj === undefined ) return chars . missingChar ;
693+ else if ( jObj === null ) return chars . nilChar ;
694+ else if ( jObj . child && Object . keys ( jObj . child ) . length === 0 && ( ! jObj . attrsMap || Object . keys ( jObj . attrsMap ) . length === 0 ) ) {
695+ return chars . emptyChar ;
696+ } else {
697+ return true ;
698+ }
699+ }
700+
701+ var convert2nimn = function ( node , e_schema , options ) {
702+ options = Object . assign ( { } , defaultOptions , options ) ;
703+ return _e ( node , e_schema , options )
704+ }
705+
706+ //exports.convert2nimn = _e;
707+ exports . convert2nimn = convert2nimn ;
708+ } , { } ] , 4 :[ function ( require , module , exports ) {
560709exports . parse = require ( "./x2j" ) . parse ;
710+ exports . convertTonimn = require ( "../src/nimndata" ) . convert2nimn ;
561711exports . getTraversalObj = require ( "./x2j" ) . getTraversalObj ;
562712exports . convertToJson = require ( "./x2j" ) . convertToJson ;
563713exports . validate = require ( "./validator" ) . validate ;
564714exports . j2xParser = require ( "./j2x" ) ;
565715
566- } , { "./ j2x" :2 , "./validator" :5 , "./x2j" :6 } ] , 4 :[ function ( require , module , exports ) {
716+ } , { "../src/nimndata" : 3 , "./ j2x" :2 , "./validator" :6 , "./x2j" :7 } ] , 5 :[ function ( require , module , exports ) {
567717var getAllMatches = function ( string , regex ) {
568718 var matches = [ ] ;
569719 var match = regex . exec ( string ) ;
@@ -631,7 +781,7 @@ var fakeCallNoReturn = function() {}
631781exports . doesMatch = doesMatch
632782exports . doesNotMatch = doesNotMatch
633783exports . getAllMatches = getAllMatches ;
634- } , { } ] , 5 :[ function ( require , module , exports ) {
784+ } , { } ] , 6 :[ function ( require , module , exports ) {
635785var util = require ( "./util" ) ;
636786
637787
@@ -668,16 +818,9 @@ exports.validate = function(xmlData, options){
668818
669819 i ++ ;
670820 if ( xmlData [ i ] === "?" ) {
671- if ( i !== 1 ) {
672- return { err : { code : "InvalidXml" , msg : "XML declaration allowed only at the start of the document." } } ;
673- } else {
674- //read until ?> is found
675- for ( ; i < xmlData . length ; i ++ ) {
676- if ( xmlData [ i ] == "?" && xmlData [ i + 1 ] == ">" ) {
677- i ++ ;
678- break ;
679- }
680- }
821+ i = readPI ( xmlData , ++ i ) ;
822+ if ( i . err ) {
823+ return i ;
681824 }
682825 } else if ( xmlData [ i ] === "!" ) {
683826 i = readCommentAndCDATA ( xmlData , i ) ;
@@ -772,7 +915,29 @@ exports.validate = function(xmlData, options){
772915
773916 return true ;
774917}
775-
918+ /**
919+ * Read Processing insstructions and skip
920+ * @param {* } xmlData
921+ * @param {* } i
922+ */
923+ function readPI ( xmlData , i ) {
924+ var start = i ;
925+ for ( ; i < xmlData . length ; i ++ ) {
926+ if ( xmlData [ i ] == "?" || xmlData [ i ] == " " ) { //tagname
927+ var tagname = xmlData . substr ( start , i - start ) ;
928+ if ( i > 5 && tagname === "xml" ) {
929+ return { err : { code : "InvalidXml" , msg : "XML declaration allowed only at the start of the document." } } ;
930+ } else if ( xmlData [ i ] == "?" && xmlData [ i + 1 ] == ">" ) {
931+ //check if valid attribut string
932+ i ++ ;
933+ break ;
934+ } else {
935+ continue ;
936+ }
937+ }
938+ }
939+ return i ;
940+ }
776941function readCommentAndCDATA ( xmlData , i ) {
777942 if ( xmlData . length > i + 5 && xmlData [ i + 1 ] === "-" && xmlData [ i + 2 ] === "-" ) { //comment
778943 for ( i += 3 ; i < xmlData . length ; i ++ ) {
@@ -909,7 +1074,7 @@ function validateTagName(tagname){
9091074
9101075
9111076
912- } , { "./util" :4 } ] , 6 :[ function ( require , module , exports ) {
1077+ } , { "./util" :5 } ] , 7 :[ function ( require , module , exports ) {
9131078var util = require ( "./util" ) ;
9141079var xmlNode = require ( "./xmlNode" ) ;
9151080var he = require ( "he" ) ;
@@ -1105,18 +1270,18 @@ var convertToJson = function (node, options){
11051270 var jObj = { } ;
11061271
11071272 //traver through all the children
1108- for ( var index = 0 ; index < node . child . length ; index ++ ) {
1109- var prop = node . child [ index ] . tagname ;
1110- var obj = convertToJson ( node . child [ index ] , options ) ;
1111- if ( typeof jObj [ prop ] !== "undefined" ) {
1112- if ( ! Array . isArray ( jObj [ prop ] ) ) {
1113- var swap = jObj [ prop ] ;
1114- jObj [ prop ] = [ ] ;
1115- jObj [ prop ] . push ( swap ) ;
1273+ var keys = Object . keys ( node . child ) ;
1274+ for ( var index = 0 ; index < keys . length ; index ++ ) {
1275+ var tagname = keys [ index ] ;
1276+ if ( node . child [ tagname ] && node . child [ tagname ] . length > 1 ) {
1277+ jObj [ tagname ] = [ ] ;
1278+ for ( var tag in node . child [ tagname ] ) {
1279+ var obj = convertToJson ( node . child [ tagname ] [ tag ] , options ) ;
1280+ jObj [ tagname ] . push ( obj ) ;
11161281 }
1117- jObj [ prop ] . push ( obj ) ;
11181282 } else {
1119- jObj [ prop ] = options . arrayMode ? [ obj ] : obj ;
1283+ var obj = convertToJson ( node . child [ tagname ] [ 0 ] , options ) ;
1284+ jObj [ tagname ] = obj ;
11201285 }
11211286 }
11221287 util . merge ( jObj , node . attrsMap ) ;
@@ -1138,16 +1303,20 @@ exports.parse = xml2json;
11381303exports . getTraversalObj = getTraversalObj ;
11391304exports . convertToJson = convertToJson ;
11401305
1141- } , { "./util" :4 , "./xmlNode" :7 , "he" :1 } ] , 7 :[ function ( require , module , exports ) {
1306+ } , { "./util" :5 , "./xmlNode" :8 , "he" :1 } ] , 8 :[ function ( require , module , exports ) {
11421307module . exports = function ( tagname , parent , val ) {
11431308 this . tagname = tagname ;
11441309 this . parent = parent ;
1145- this . child = [ ] ; //child tags
1310+ this . child = { } ; //child tags
11461311 this . attrsMap ; //attributes map
11471312 this . val = val ; //text only
11481313 this . addChild = function ( child ) {
1149- this . child . push ( child ) ;
1314+ if ( this . child [ child . tagname ] ) { //already presents
1315+ this . child [ child . tagname ] . push ( child ) ;
1316+ } else {
1317+ this . child [ child . tagname ] = [ child ] ;
1318+ }
11501319 } ;
11511320} ;
1152- } , { } ] } , { } , [ 3 ] ) ( 3 )
1321+ } , { } ] } , { } , [ 4 ] ) ( 4 )
11531322} ) ;
0 commit comments