Converting xml of any structure to json with nested arrays

1k Views Asked by At

I have XML which can be of any structure like below. Therefore there is no POJO class for instantiation. As you can see I have nested arrays (in this case reservations is an array of two reservation and every reservation have simple elements and arrays of rooms - but that is only example - there may be more arrays and nested arrays).

<reservations>
    <reservation>
        <id>1318504</id>
        <add_date>2020-12-10 12:48:09</add_date>
        <rooms>  
            <room>
                <id>28902</id>
                <floor>2</floor>
            </room>  
            <room>
                <id>28903</id>
                <floor>3</floor>
            </room>
        </rooms>
    </reservation >
    <reservation>
        <id>1318501</id>
        <add_date>2021-05-07 07:47:05</add_date>
        <rooms>
            <room>
                <id>5</id>
                <floor>25</floor>
            </room>
            <room>
                <id>6</id>
            </room>
        </rooms>
    </reservation>
</reservations>

I need to convert it to Json as:

{
   "reservations":[
      {
         "id":"1318504",
         "add_date":"2020-12-10 12:48:09",
         "rooms":[
            {
               "id":"28902",
               "floor":2
               
            },
            {
               "id":"28903",
               "floor":3
            }
         ]
      },
      {
         "id":"1318501",
         "add_date":"2021-05-07 07:47:05",
         "rooms":[
            {
               "id":"5",
               "floor":25
               
            },
            {
               "id":"6"
            }
         ]
      }
   ]
}

 

I have read lots of topic about converting XML to Json. I tried something like:

  1. json.org

    JSONObject xmlJSONObj = XML.toJSONObject(xmlString);

  2. jackson

    JsonNode node = new XmlMapper().readTree(xmlContent);

  3. underscore-java

    String jsonString = U.xmlToJson(xmlContent)

and so on. Bu the result, in best case is like:

{
   "reservations":{
      "reservation":[
         {
            "rooms":{
               "room":[
                  {
                     "id":28902,
                     "floor":2
                  },
                  {
                     "id":28903,
                     "floor":3
                  }
               ]
            },
            "add_date":"2020-12-10 12:48:09",
            "id":1318504
         },
         {
            "rooms":{
               "room":[
                  {
                     "id":5,
                     "floor":25
                  },
                  {
                     "id":6
                  }
               ]
            },
            "add_date":"2021-05-07 07:47:05",
            "id":1318501
         }
      ]
   }
}

I don't need nodes like reservation and room. Could you help me how can I solve this problem? I can manipulate with xml or json, but the form without these nodes is my target.

2

There are 2 best solutions below

0
On

You may be able to use json:Array="true" in the array - and the JsonConvert will interpret it correctly.

https://www.newtonsoft.com/json/help/html/ConvertXmlToJsonForceArray.htm

0
On

The solution:

import com.github.underscore.U;

    String xml = "<reservations>\n"
          + "    <reservation>\n"
          + "        <id>1318504</id>\n"
          + "        <add_date>2020-12-10 12:48:09</add_date>\n"
          + "        <rooms>  \n"
          + "            <room>\n"
          + "                <id>28902</id>\n"
          + "                <floor>2</floor>\n"
          + "            </room>  \n"
          + "            <room>\n"
          + "                <id>28903</id>\n"
          + "                <floor>3</floor>\n"
          + "            </room>\n"
          + "        </rooms>\n"
          + "    </reservation >\n"
          + "    <reservation>\n"
          + "        <id>1318501</id>\n"
          + "        <add_date>2021-05-07 07:47:05</add_date>\n"
          + "        <rooms>\n"
          + "            <room>\n"
          + "                <id>5</id>\n"
          + "                <floor>25</floor>\n"
          + "            </room>\n"
          + "            <room>\n"
          + "                <id>6</id>\n"
          + "            </room>\n"
          + "        </rooms>\n"
          + "    </reservation>\n"
          + "</reservations>";
    Map<String, Object> map = U.fromXmlMap(xml);
    U.set(map, "reservations", U.get(map, "reservations.reservation"));
    List<Map<String, Object>> list = U.get(map, "reservations");
    for (Map<String, Object> item : list) {
        U.set(item, "rooms", U.get(item, "rooms.room"));
    }
    System.out.println(U.toJson(map));

Result:

{
  "reservations": [
    {
      "id": "1318504",
      "add_date": "2020-12-10 12:48:09",
      "rooms": [
        {
          "id": "28902",
          "floor": "2"
        },
        {
          "id": "28903",
          "floor": "3"
        }
      ]
    },
    {
      "id": "1318501",
      "add_date": "2021-05-07 07:47:05",
      "rooms": [
        {
          "id": "5",
          "floor": "25"
        },
        {
          "id": "6"
        }
      ]
    }
  ],
  "#omit-xml-declaration": "yes"
}