@@ -355,10 +355,20 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
355355 && TYPE_ATTR .equals (string )) {
356356 xmlXsiTypeConverter = config .getXsiTypeMap ().get (token );
357357 } else if (!nilAttributeFound ) {
358- jsonObject .accumulate (string ,
359- config .isKeepStrings ()
360- ? ((String ) token )
361- : stringToValue ((String ) token ));
358+ Object obj = stringToValue ((String ) token );
359+ if (obj instanceof Boolean ) {
360+ jsonObject .accumulate (string ,
361+ config .isKeepBooleanAsString ()
362+ ? ((String ) token )
363+ : obj );
364+ } else if (obj instanceof Number ) {
365+ jsonObject .accumulate (string ,
366+ config .isKeepNumberAsString ()
367+ ? ((String ) token )
368+ : obj );
369+ } else {
370+ jsonObject .accumulate (string , stringToValue ((String ) token ));
371+ }
362372 }
363373 token = null ;
364374 } else {
@@ -407,8 +417,20 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
407417 jsonObject .accumulate (config .getcDataTagName (),
408418 stringToValue (string , xmlXsiTypeConverter ));
409419 } else {
410- jsonObject .accumulate (config .getcDataTagName (),
411- config .isKeepStrings () ? string : stringToValue (string ));
420+ Object obj = stringToValue ((String ) token );
421+ if (obj instanceof Boolean ) {
422+ jsonObject .accumulate (config .getcDataTagName (),
423+ config .isKeepBooleanAsString ()
424+ ? ((String ) token )
425+ : obj );
426+ } else if (obj instanceof Number ) {
427+ jsonObject .accumulate (config .getcDataTagName (),
428+ config .isKeepNumberAsString ()
429+ ? ((String ) token )
430+ : obj );
431+ } else {
432+ jsonObject .accumulate (config .getcDataTagName (), stringToValue ((String ) token ));
433+ }
412434 }
413435 }
414436
@@ -688,6 +710,44 @@ public static JSONObject toJSONObject(Reader reader, boolean keepStrings) throws
688710 return toJSONObject (reader , XMLParserConfiguration .ORIGINAL );
689711 }
690712
713+ /**
714+ * Convert a well-formed (but not necessarily valid) XML into a
715+ * JSONObject. Some information may be lost in this transformation because
716+ * JSON is a data format and XML is a document format. XML uses elements,
717+ * attributes, and content text, while JSON uses unordered collections of
718+ * name/value pairs and arrays of values. JSON does not does not like to
719+ * distinguish between elements and attributes. Sequences of similar
720+ * elements are represented as JSONArrays. Content text may be placed in a
721+ * "content" member. Comments, prologs, DTDs, and <pre>{@code
722+ * <[ [ ]]>}</pre>
723+ * are ignored.
724+ *
725+ * All numbers are converted as strings, for 1, 01, 29.0 will not be coerced to
726+ * numbers but will instead be the exact value as seen in the XML document depending
727+ * on how flag is set.
728+ * All booleans are converted as strings, for true, false will not be coerced to
729+ * booleans but will instead be the exact value as seen in the XML document depending
730+ * on how flag is set.
731+ *
732+ * @param reader The XML source reader.
733+ * @param keepNumberAsString If true, then numeric values will not be coerced into
734+ * numeric values and will instead be left as strings
735+ * @param keepBooleanAsString If true, then boolean values will not be coerced into
736+ * * numeric values and will instead be left as strings
737+ * @return A JSONObject containing the structured data from the XML string.
738+ * @throws JSONException Thrown if there is an errors while parsing the string
739+ */
740+ public static JSONObject toJSONObject (Reader reader , boolean keepNumberAsString , boolean keepBooleanAsString ) throws JSONException {
741+ XMLParserConfiguration xmlParserConfiguration = new XMLParserConfiguration ();
742+ if (keepNumberAsString ) {
743+ xmlParserConfiguration = xmlParserConfiguration .withKeepNumberAsString (keepNumberAsString );
744+ }
745+ if (keepBooleanAsString ) {
746+ xmlParserConfiguration = xmlParserConfiguration .withKeepBooleanAsString (keepBooleanAsString );
747+ }
748+ return toJSONObject (reader , xmlParserConfiguration );
749+ }
750+
691751 /**
692752 * Convert a well-formed (but not necessarily valid) XML into a
693753 * JSONObject. Some information may be lost in this transformation because
@@ -746,6 +806,38 @@ public static JSONObject toJSONObject(String string, boolean keepStrings) throws
746806 return toJSONObject (new StringReader (string ), keepStrings );
747807 }
748808
809+ /**
810+ * Convert a well-formed (but not necessarily valid) XML string into a
811+ * JSONObject. Some information may be lost in this transformation because
812+ * JSON is a data format and XML is a document format. XML uses elements,
813+ * attributes, and content text, while JSON uses unordered collections of
814+ * name/value pairs and arrays of values. JSON does not does not like to
815+ * distinguish between elements and attributes. Sequences of similar
816+ * elements are represented as JSONArrays. Content text may be placed in a
817+ * "content" member. Comments, prologs, DTDs, and <pre>{@code
818+ * <[ [ ]]>}</pre>
819+ * are ignored.
820+ *
821+ * All numbers are converted as strings, for 1, 01, 29.0 will not be coerced to
822+ * numbers but will instead be the exact value as seen in the XML document depending
823+ * on how flag is set.
824+ * All booleans are converted as strings, for true, false will not be coerced to
825+ * booleans but will instead be the exact value as seen in the XML document depending
826+ * on how flag is set.
827+ *
828+ * @param string
829+ * The source string.
830+ * @param keepNumberAsString If true, then numeric values will not be coerced into
831+ * numeric values and will instead be left as strings
832+ * @param keepBooleanAsString If true, then boolean values will not be coerced into
833+ * numeric values and will instead be left as strings
834+ * @return A JSONObject containing the structured data from the XML string.
835+ * @throws JSONException Thrown if there is an errors while parsing the string
836+ */
837+ public static JSONObject toJSONObject (String string , boolean keepNumberAsString , boolean keepBooleanAsString ) throws JSONException {
838+ return toJSONObject (new StringReader (string ), keepNumberAsString , keepBooleanAsString );
839+ }
840+
749841 /**
750842 * Convert a well-formed (but not necessarily valid) XML string into a
751843 * JSONObject. Some information may be lost in this transformation because
0 commit comments