2

I converted my XML to Json successfully using the below code.

I ran into this issue, i have two different XML strings in the below program.

First one has single value for user name and the second one has two values.

first xml produces the json without Square braces.and the second xml with Square braces.

I want both of them to have square braces. Is there a way to typecast cast the username as array in output string?

Primarily, I want both of them to look like arrays in output json.

package com.java.json;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.xml.XMLSerializer;

public class XmlSerializer {

public static void main(String[] args) throws Exception {
String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">[email protected]</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";
//String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">[email protected]</username><username xsi:type=\"xsd:string\">[email protected]</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";

JsonConfig conf =  new JsonConfig();
XMLSerializer xs = new XMLSerializer();

xs.setForceTopLevelObject(true);   
xs.setSkipWhitespace(true);
xs.setTrimSpaces(true);    
xs.setSkipNamespaces(true);
xs.setRemoveNamespacePrefixFromElements(true);

JSONObject jsonobj = (JSONObject) xs.read(xmlstring);    
String  jsonstring  = jsonobj.toString().replace("\"@", "\"");    

System.out.println(jsonstring);     

}
} 

First XML should give output like this.

{"Envelope":{"Header":{"authInfo":{"type":"soap:authentication","username":[null],"password":null}}}}

Currently it is giving like this.

{"Envelope":{"Header":{"authInfo":{"type":"soap:authentication","username":null,"password":null}}}}

The second XML in the above program is good and it gives output like this.

{"Envelope":{"Header":{"authInfo":{"type":"soap:authentication","username":[null,null],"password":null}}}}

Thanks in advance.

3
  • Why do you expect single element to be serialized into an array? Commented Dec 2, 2015 at 22:09
  • We have a down stream process after serialization, it expects username as array. That process will fail if it is not inside square braces. We do not mind if we can add these braces after serialization in cases of single valued arrays. We just need that to be coming in square braces. We can manually doit by parsing json and adding those in worst case but i am trying for a better way to define the type of Username as array in output json by some how like casting money as array and adding those braces. Commented Dec 3, 2015 at 15:13
  • Ok, if you really don't want to do this manually.. I think something like this may work (but I'm not 100% sure) - build class that represents your XML/JSON structure and declare username field as List<String>. Then use some framework like jackson to parse your XML into instance of this class and then serialize this object to JSON. This could work (maybe with some extra config). But IMHO - effort bigger than benefit. Commented Dec 3, 2015 at 21:22

1 Answer 1

1

After a Good amount of research I found out the best way to handle the problem.

You can convert any XML to JSON without loosing the type Information and Array issue by using the code snippet below.

We need the Java POJO to convert this way like below.

By using The AuthInfo.class in below code. I am getting the JSON with proper Data Types.

You can convert any complex XML to JSON in this method.

package com.java.json;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.jaxb.XmlJaxbAnnotationIntrospector;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import com.tda.trident.beb.AuthInfo;

public class XmlDoc {

public static void main(String[] args) throws Exception {
    String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">[email protected]</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";
    //String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">[email protected]</username><username xsi:type=\"xsd:string\">[email protected]</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";
    Object messageObj = null;       

    XmlMapper unmarshaller = new XmlMapper();
    unmarshaller.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    XmlJaxbAnnotationIntrospector xmlIntrospector = new XmlJaxbAnnotationIntrospector();
    unmarshaller.setAnnotationIntrospector(xmlIntrospector);
    JaxbAnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
    ObjectMapper marshaller = new ObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    marshaller.setSerializationInclusion(Include.NON_NULL);
    marshaller.setAnnotationIntrospector(introspector);

    TransactionTradeMessage rootNode = unmarshaller.readValue(xmlstring, AuthInfo.class);

    messageObj = rootNode.getTransactionTrade();

    System.out.println(marshaller.writeValueAsString(messageObj));

}
}
Sign up to request clarification or add additional context in comments.

1 Comment

It is so rare to see ANY real answer to this question! Does this solution act on ALL single value objects in the XML or is there a way to target it to only act on certain nodes(xml) / values (JSON)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.