0

I need to write a library that converts XML to Json. I have been trying and using help from one of the answers on SO, i could do this:

Example of the xml:

<website>
<created-at  type="datetime"> 2010-02-17T14:36:26-08:00</created-at>
<id  type=

"integer"> 12</id>
    <primary-host-id  type="integer"  nil="true"></primary-host-id>
    <suspended  type="boolean"> false</suspended>
    <hosts  type="array">
<host>
    <id  type="integer"> 12</id>
    <name> example.viviti.com</name>
</host>
<host>
    <id  type="integer"> 12</id>
    <name> example.viviti.com</name>
    </host>
</hosts>
    <ip-address> 127.0.0.1</ip-address>
    </website>

So, I have wrote a code what produces this json,

{ip-address= 127.0.0.1, hosts={host=[{name= example.viviti.com, id= 12}, {name= example.viviti.com, id= 12}]}, created-at= 2010-02-17T14:36:26-08:00, id= 12, primary-host-id=, suspended= false}

It is making "host" as array, but what i need is "hosts" to be an array. So, the expected json would be something like:

    {
  "website":{
     "created-at":"2010-02-17T14:36:26-08:00",
     "id":"12",
     "suspended":"false",
     "ip-primary-host-id":"",
     "ip-address":"127.0.0.1",
     "hosts":[
        {
           "host":{
              "name":"example.viviti.com",
              "id":"12"
           }
        },
        {
           "host":{
              "name":"example1.viviti.com",
              "id":"13"
           }
        }
     ]
  }
}

This is my existing code:

public static void main(String[] args) throws Exception
    {


        XStream magicApi = new XStream();
        magicApi.registerConverter(new MapEntryConverter());
        magicApi.alias("website", Map.class);



        Map extractedMap = (Map) magicApi.fromXML(RESPONSE);
        System.out.println(extractedMap);

    }

    public static class MapEntryConverter implements Converter
    {

        public boolean canConvert(Class clazz)
        {
            return AbstractMap.class.isAssignableFrom(clazz);
        }

        public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context)
        {

            AbstractMap map = (AbstractMap) value;
            for (Object obj : map.entrySet())
            {
                Map.Entry entry = (Map.Entry) obj;
                writer.startNode(entry.getKey().toString());
                Object val = entry.getValue();
                if (null != val)
                {
                    writer.setValue(val.toString());
                }
                writer.endNode();
            }

        }

        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context)
        {

            Map<String, Object> map = new HashMap<String, Object>();

            while (reader.hasMoreChildren())
            {
                reader.moveDown();

                String key = reader.getNodeName();

                if(reader.hasMoreChildren())
                {
//                    reader.moveDown();

                    Object interim = unmarshal(reader, context);
                    if(!map.containsKey(key))
                    {
                        map.put(key, interim);
                    }
                    else
                    {
                        List list = new ArrayList();
                        list.add(map.get(key));
                        list.add(interim);
                        map.put(key,list);
                    }
//                    reader.moveUp();
                }
                else
                {
                    String value = reader.getValue();
                    map.put(key, value);
                }

                reader.moveUp();
            }

            return map;
        }

    }

Also, i do not want the XML namespaces in the json. Appreciate the help.

doctore
  • 518
  • 9
  • 18

1 Answers1

0

Why don't you use JSONObject. It's much simpler to generate JSON using this object. It will save you lots and lots of LOC.

public class Main {

    public static void main(String[] args) {
        try {
            JSONObject xmlJSONObj = XML.toJSONObject(YOUR_XML_STRING);
            System.out.println(xmlJSONObj.toString());
        } catch (JSONException je) {
            System.out.println(je.toString());
        }
    }
}

Output

{
    "website": {
        "created-at": {
            "-type": "datetime",
            "#text": " 2010-02-17T14:36:26-08:00"
        },
        "id": {
            "-type": "integer",
            "#text": " 12"
        },
        "primary-host-id": {
            "-type": "integer",
            "-nil": "true"
        },
        "suspended": {
            "-type": "boolean",
            "#text": " false"
        },
        "hosts": {
            "-type": "array",
            "host": [
                {
                    "id": {
                        "-type": "integer",
                        "#text": " 12"
                    },
                    "name": " example.viviti.com"
                },
                {
                    "id": {
                        "-type": "integer",
                        "#text": " 12"
                    },
                    "name": " example.viviti.com"
                }
            ]
        },
        "ip-address": " 127.0.0.1"
    }
}

more info...

Community
  • 1
  • 1
Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
  • This will result in a similar json as I am getting now. Also, i want to remove the namespaces which it doesn't. – doctore Jul 22 '16 at 12:03
  • both of the JSON that you've mentioned in your question are invalid. you can parse them [here](http://codebeautify.org/jsonviewer) and see the results for yourself. – Raman Sahasi Jul 22 '16 at 12:14
  • The JSON might be incorrect (a couple of paranthesis might be extra or missing) but that's not my concern. I am talking about the inner elements. I will also post the correct json's. – doctore Jul 22 '16 at 13:20