1010import java .math .BigInteger ;
1111import java .util .*;
1212import java .io .BufferedReader ;
13- import java .io . Reader ;
13+ import java .util . function . Function ;
1414import java .util .stream .Collectors ;
1515
1616/**
@@ -484,7 +484,10 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
484484 }
485485
486486 // overwritten method of parse which allows to pass a prefix tag
487- private static boolean parse (XMLTokener x , JSONObject context , String name , String prefix , XMLParserConfiguration config , int currentNestingDepth )
487+ /* Milestone3
488+ overwritten new method of parse
489+ */
490+ private static boolean parseMilestone3 (XMLTokener x , JSONObject context , String name , XMLParserConfiguration config , int currentNestingDepth ,Function <String , String > keyTransformer )
488491 throws JSONException {
489492 char c ;
490493 int i ;
@@ -567,6 +570,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, Stri
567570
568571 } else {
569572 tagName = (String ) token ;
573+ String transformedTagName = keyTransformer .apply (tagName );//add
570574 token = null ;
571575 jsonObject = new JSONObject ();
572576 boolean nilAttributeFound = false ;
@@ -584,7 +588,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, Stri
584588 if (!(token instanceof String )) {
585589 throw x .syntaxError ("Missing value" );
586590 }
587-
591+ String transformedKey = keyTransformer . apply ( string ); //add new code
588592 if (config .isConvertNilAttributeToNull ()
589593 && NULL_ATTR .equals (string )
590594 && Boolean .parseBoolean ((String ) token )) {
@@ -593,6 +597,14 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, Stri
593597 && TYPE_ATTR .equals (string )) {
594598 xmlXsiTypeConverter = config .getXsiTypeMap ().get (token );
595599 } else if (!nilAttributeFound ) {
600+ Object obj = stringToValue ((String ) token );
601+ jsonObject .accumulate (transformedKey , obj );
602+ }
603+ token = null ;
604+ } else {
605+ jsonObject .accumulate (keyTransformer .apply (string ), "" );
606+ }
607+ /*} else if (!nilAttributeFound) {
596608 Object obj = stringToValue((String) token);
597609 if (obj instanceof Boolean) {
598610 jsonObject.accumulate(prefix + string,
@@ -612,13 +624,33 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, Stri
612624 } else {
613625 jsonObject.accumulate(prefix + string, "");
614626 }
627+ */
615628
616629
617630 } else if (token == SLASH ) {
618631 // Empty tag <.../>
619632 if (x .nextToken () != GT ) {
620633 throw x .syntaxError ("Misshaped tag" );
621634 }
635+ if (config .getForceList ().contains (tagName )) {
636+ if (nilAttributeFound ) {
637+ context .append (transformedTagName , JSONObject .NULL );
638+ } else if (jsonObject .length () > 0 ) {
639+ context .append (transformedTagName , jsonObject );
640+ } else {
641+ context .put (transformedTagName , new JSONArray ());
642+ }
643+ } else {
644+ if (nilAttributeFound ) {
645+ context .accumulate (transformedTagName , JSONObject .NULL );
646+ } else if (jsonObject .length () > 0 ) {
647+ context .accumulate (transformedTagName , jsonObject );
648+ } else {
649+ context .accumulate (transformedTagName , "" );
650+ }
651+ }
652+ return false ;
653+ /*
622654 if (config.getForceList().contains(prefix + tagName)) {
623655 // Force the value to be an array
624656 if (nilAttributeFound) {
@@ -638,7 +670,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, Stri
638670 }
639671 }
640672 return false;
641-
673+ */
642674 } else if (token == GT ) {
643675 // Content, between <...> and </...>
644676 for (;;) {
@@ -673,7 +705,41 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, Stri
673705 }
674706
675707 } else if (token == LT ) {
708+ if (parseMilestone3 (x , jsonObject ,tagName , config , currentNestingDepth + 1 , keyTransformer )) {
709+ if (config .getForceList ().contains (tagName )) {
710+ if (jsonObject .length () == 0 ) {
711+ context .put (transformedTagName , new JSONArray ());
712+ } else if (jsonObject .length () == 1
713+ && jsonObject .opt (config .getcDataTagName ()) != null ) {
714+ context .append (transformedTagName , jsonObject .opt (config .getcDataTagName ()));
715+ } else {
716+ context .append (transformedTagName , jsonObject );
717+ }
718+ } else {
719+ if (jsonObject .length () == 0 ) {
720+ context .accumulate (transformedTagName , "" );
721+ } else if (jsonObject .length () == 1
722+ && jsonObject .opt (config .getcDataTagName ()) != null ) {
723+ context .accumulate (transformedTagName , jsonObject .opt (config .getcDataTagName ()));
724+ } else {
725+ context .accumulate (transformedTagName , jsonObject );
726+ }
727+ }
728+ return false ;
729+ }
730+ }
731+ }
732+ } else {
733+ throw x .syntaxError ("Misshaped tag" );
734+ }
735+ }
736+ }
737+ }
738+ }
739+
740+
676741 // Nested element
742+ /*
677743 if (currentNestingDepth == config.getMaxNestingDepth()) {
678744 throw x.syntaxError("Maximum nesting depth of " + config.getMaxNestingDepth() + " reached");
679745 }
@@ -713,6 +779,8 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, Stri
713779 }
714780 }
715781 }
782+
783+ */
716784 /**
717785 * This method removes any JSON entry which has the key set by XMLParserConfiguration.cDataTagName
718786 * and contains whitespace as this is caused by whitespace between tags. See test XMLTest.testNestedWithWhitespaceTrimmingDisabled.
@@ -1188,11 +1256,24 @@ public static JSONObject toJSONObject(Reader reader, JSONPointer path) throws JS
11881256
11891257 /**
11901258 * Given a customized function, convert the keys in the Json Object
1191- * @param reader
1192- * @param prefix
1193- * @return
1194- * @throws JSONException
1259+ * @param reader the XML input
1260+ * @param keyTransformer a function that transforms each key name
1261+ * @return JSONObject with transformed keys
1262+ * @throws JSONException if any XML parsing or transformation fails
11951263 */
1264+ public static JSONObject toJSONObject (Reader reader , Function <String , String > keyTransformer ) throws JSONException {
1265+ JSONObject result = new JSONObject ();
1266+ XMLTokener x = new XMLTokener (reader );
1267+
1268+ while (x .more ()) {
1269+ x .skipPast ("<" );
1270+ if (x .more ()) {
1271+ XML .parseMilestone3 (x , result , null , XMLParserConfiguration .ORIGINAL , 0 , keyTransformer );
1272+ }
1273+ }
1274+ return result ;
1275+ }
1276+ /*
11961277 public static JSONObject toJSONObject(Reader reader, String prefix) throws JSONException {
11971278 JSONObject jo = new JSONObject();
11981279 XMLParserConfiguration config = XMLParserConfiguration.ORIGINAL;
@@ -1205,7 +1286,7 @@ public static JSONObject toJSONObject(Reader reader, String prefix) throws JSONE
12051286 }
12061287 return jo;
12071288 }
1208-
1289+ */
12091290 /**
12101291 * Helper method: skip the current element and its entire subtree without
12111292 * building any JSON output.
@@ -1868,7 +1949,6 @@ public static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObjec
18681949 }
18691950 }
18701951
1871-
18721952 /**
18731953 * Convert a well-formed (but not necessarily valid) XML string into a
18741954 * JSONObject. Some information may be lost in this transformation because
0 commit comments