Search code examples
javajsonxmlserializationjson-lib

Xml to JSON Single Valued Array handling


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.


Solution

  • 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));
    
    }
    }