Reputation: 4614
My xml contains attribute value "0123" which I want to treat as string, after conversion from xml to json as per following code leading zero gets discarded from attribute value.
Used classes
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.json.JSONObject;
import org.json.XML;
//Covert xml to json
org.jdom.Document jdomDocument = new Document();
org.jdom.Element Attribute = new org.jdom.Element("Attribute");
jdomDocument.setRootElement(Attribute);
org.jdom.Element valueElement = new org.jdom.Element("Value");
valueElement.setText(getValue()); // "0123"
// getValue() return anything like boolean,string,long,date, time etc..
root.addContent(valueElement);
String xmlval = new XMLOutputter(Format.getPrettyFormat()).outputString(jdomDocument);
JSONObject xmlJSONObj = XML.toJSONObject(xmlval);
String jsonPrettyPrintString = xmlJSONObj.toString(4);
How to resolve this issue ?
Upvotes: 2
Views: 5960
Reputation: 4614
It works :)
Added value in CDATA section so while conversion from xml to json value display as it is
org.jdom.Element valueElement = new org.jdom.Element("Value");
org.jdom.CDATA cdata = new org.jdom.CDATA(getValue());
valueElement.setText(cdata );
Upvotes: 1
Reputation: 2216
looking at the code for XML.java - in particular the stringToValue method which does
"Try to convert a string into a number, boolean, or null".
The code is below - you can see it tries to parse as a number first, in which case it will trim the leading zeros. To test you could try adding a non-numeric character in your string - I think it would then preserve the leading zeros.
It looks like the behaviour you're seeing is baked into the library. Which is not great, even though the docs for the function toJSONObject do warn
"Some information may be lost in this transformation because JSON is a data format and XML is a document format"
teh codez :
// If it might be a number, try converting it. If that doesn't work,
// return the string.
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) {
}
EDIT : this looks like a bug in the library. I believe it should use
(negative ? 1 : 0)
because the current behaviour wrongly interprets a value with a single leading zero as being a number. It correctly recognizes two or more leading zeros as being a string, as confirmed by the asker.
Upvotes: 2