json.org zeros are saved as strings and not as numbers

1.4k views Asked by At

i am using org.json to convert a big xml to a json string. however it seems that for the number 0 it creates a string "0", while other numbers like 5 or 2 work fine and become real numbers.

xml:

<w count="2" winline="5" freespins="0" jackpot="false" start="0" payout="500" supergames="0" />

java:

JSONObject json = XML.toJSONObject(xml);
String jsontext = json.toString();

resulting json:

"w":[{"supergames":"0","freespins":"0","winline":5,"count":2,"start":"0","jackpot":false,"payout":500}

is there any way to make the 0 become real 0-numbers instead of strings?

2

There are 2 answers

3
Bert F On BEST ANSWER

Looks like a bug. I looked at the source and it looks like it may throw IndexOutOfBoundsException, which basically resulting in a failed conversion to a number:

https://github.com/douglascrockford/JSON-java/blob/master/XML.java (line 327):

if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {

Throws if string starts with "0" and is only 1 character long, i.e. if the string is "0". The exception is caught and the conversion method basically just returns the original string ("0") again unconverted.

Not many options:

  1. Report the bug and hope for speedy fix.
  2. Fix it yourself for now in your own copy of the file(s).
  3. If your situation can accept 0.0 in lieu of 0, then munge the "0"'s in the XML to be "0.0"'s. (credit @bestsss)
3
Luciano Fiandesio On

Here is the snippet of code that transform an XML attribute into a JSON value.

I may be wrong, but the case where the value is "0" is not handled.

try {
            char initial = string.charAt(0);
            boolean negative = false;
            if (initial == '-') {
                initial = string.charAt(1);
                negative = true;
            }
            if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {
                return string;
            }
            if ((initial >= '0' && initial <= '9')) {
                if (string.indexOf('.') >= 0) {
                    return Double.valueOf(string);
                } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) {
                    Long myLong = new Long(string);
                    if (myLong.longValue() == myLong.intValue()) {
                        return new Integer(myLong.intValue());
                    } else {
                        return myLong;
                    }
                }
            }
        }  catch (Exception ignore) {
        }