Handle CSV, JSON and XML with Java

· 2314 words · 11 minute read

Info

In this guide we will parse an array list of hash maps into CSV, JSON and XML. The core concepts can be applied to parsing pretty much anything.

CSV ##

Example for data in the CSV format:

1name,surname,age
2john,doe,45
3jan,doe,35

Tabular presentation:

indexnamesurnameage
0johndoe45
1jandoe35

Parsing values separated by comma is by far the easiest of the three encodings in this guide. Keep the separator in mind (here ,, but could be any of: ;, |, : or \t) and check for a header row.

To keep this guide simple we hard-code the header keys and will not parse them dynamically:

Decoding ###

To convert a data from CSV to Hash maps in a array list we will first read a file (data.csv) with the above content.

 1import java.io.BufferedReader;
 2import java.io.FileReader;
 3import java.util.ArrayList;
 4import java.util.HashMap;
 5
 6public class Main {
 7    public static void main(String[] args) {
 8        ArrayList<HashMap<String, String>> result = new ArrayList<>();
 9        try{
10            // open the 'data.csv' file and create a reader
11            FileReader fileReader = new FileReader("data.csv");
12            // pass the reader to a buffered reader
13            BufferedReader bufferedReader = new BufferedReader(fileReader);
14
15            bufferedReader
16                // loop over the lines using the .lines() method
17                // which returns a stream
18                .lines()
19                // skip the header line
20                .skip(1)
21                // iterate over each line
22                .forEach(l -> {
23                    // allocate a new hash map
24                    HashMap<String, String> temp = new HashMap<>();
25
26                    // split the line via its separator
27                    String[] splitLine = l.split(",");
28                    // assign the values to the know keys
29                    temp.put("name", splitLine[0]);
30                    temp.put("surname", splitLine[1]);
31                    temp.put("age", splitLine[2]);
32
33                    // add the hash map to the result list
34                    result.add(temp);
35                });
36        } catch (Exception e){
37            // prints out if file cant be found or read
38            e.printStackTrace();
39        }
40
41        // print all hash maps in the list
42        result.forEach(System.out::println);
43    }
44}

Running the above yields the following result:

1{surname=doe, name=john, age=45}
2{surname=doe, name=jan, age=35}

Encoding ###

Encoding to csv is also very simple, instantiate a StringBuilder, append the header and after that append each line:

 1import java.io.BufferedReader;
 2import java.io.FileReader;
 3import java.util.ArrayList;
 4import java.util.HashMap;
 5
 6public class Main {
 7    public static void main(String[] args) {
 8        ArrayList<HashMap<String, String>> result = new ArrayList<>();
 9        try{
10            // open the 'data.csv' file and create a reader
11            FileReader fileReader = new FileReader("data.csv");
12            // pass the reader to a buffered reader
13            BufferedReader bufferedReader = new BufferedReader(fileReader);
14
15            bufferedReader
16                // loop over the lines using the .lines() method
17                // which returns a stream
18                .lines()
19                // skip the header line
20                .skip(1)
21                // iterate over each line
22                .forEach(l -> {
23                    // allocate a new hash map
24                    HashMap<String, String> temp = new HashMap<>();
25
26                    // split the line via its separator
27                    String[] splitLine = l.split(",");
28                    // assign the values to the know keys
29                    temp.put("name", splitLine[0]);
30                    temp.put("surname", splitLine[1]);
31                    temp.put("age", splitLine[2]);
32
33                    // add the hash map to the result list
34                    result.add(temp);
35                });
36        } catch (Exception e){
37            // prints out if the csv is invalid or file cant be found / read
38            e.printStackTrace();
39        }
40
41        // print all hash maps in the list
42        result.forEach(System.out::println);
43
44        StringBuilder stringBuilder = new StringBuilder();
45
46        // append the header row + the line separator of the system
47        stringBuilder
48            .append("name,surname,age")
49            .append(System.lineSeparator());
50
51        // loop over each line
52        result.forEach(e -> {
53            // create the row by getting the values from the current hash map
54            String formattedRow = String.format("%s,%s,%s,%s",
55                    e.get("name"),
56                    e.get("surname"),
57                    e.get("age"),
58                    System.lineSeparator());
59            // add the new row to the string builder
60            stringBuilder.append(formattedRow);
61        });
62
63        System.out.println(stringBuilder);
64    }
65}

Running the above yields the following result:

1{surname=doe, name=john, age=45}
2{surname=doe, name=jan, age=35}
3name,surname,age
4john,doe,45
5jan,doe,35

As expected, first the two decoded rows, afterwards the encoded representation as csv with the header row.

XML ##

XML is a somewhat outdated data exchange format, but especially people around java use it for configurations and data storage. The format is a lot more verbose, especially compared to csv.

Example for data in the XML format:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<root>
 3    <person>
 4        <name>John</name>
 5        <surname>Doe</surname>
 6        <age>45</age>
 7    </person>
 8    <person>
 9        <name>Jan</name>
10        <surname>Doe</surname>
11        <age>35</age>
12    </person>
13</root>

Decoding ###

Parsing XML requires a lot of boilerplate in Java so be prepared. I copied the above XML to a data.xml file.

 1import org.w3c.dom.Document;
 2import org.w3c.dom.Element;
 3import org.w3c.dom.Node;
 4import org.w3c.dom.NodeList;
 5
 6import javax.xml.parsers.DocumentBuilder;
 7import javax.xml.parsers.DocumentBuilderFactory;
 8import java.util.ArrayList;
 9import java.util.HashMap;
10
11public class Main {
12    public static void main(String[] args) {
13        // result list which contains all parsed rows
14        ArrayList<HashMap<String, String>> result = new ArrayList<>();
15        try {
16            // create a factory
17            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
18            // use the above factory to get a document builder
19            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
20            // use the document builder to parse the xml in the file 'data.xml'
21            Document doc = documentBuilder.parse("data.xml");
22
23            // get the list of persons
24            NodeList personList = doc.getElementsByTagName("person");
25            // loop over the list of person
26            for (int i = 0; i < personList.getLength(); i++) {
27                // create a node out of the current item
28                Node item = personList.item(i);
29                // check if the node is an Element
30                if (item.getNodeType() == Node.ELEMENT_NODE) {
31                    // new hash map to contain the values of the row
32                    HashMap<String, String> temp = new HashMap<>();
33                    // put all values for the keys into the above map
34                    temp.put("name", ((Element) item)
35                        .getElementsByTagName("name")
36                        .item(0)
37                        .getTextContent());
38
39                    temp.put("surname", ((Element) item)
40                        .getElementsByTagName("surname")
41                        .item(0)
42                        .getTextContent());
43
44                    temp.put("age", ((Element) item)
45                        .getElementsByTagName("age")
46                        .item(0)
47                        .getTextContent());
48
49                    // add the row to the result list
50                    result.add(tmap);
51                }
52           }
53        } catch (Exception e) {
54            // triggers if xml is invalid or the file cant be opened
55            e.printStackTrace();
56        }
57        // print the list
58        result.forEach(System.out::println);
59    }
60}

Running the above yields the following result:

1{surname=Doe, name=John, age=45}
2{surname=Doe, name=Jan, age=35}

Encoding ###

Converting the parsed data back into XML requires even more boilerplate so read the comments carefully:

  1import org.w3c.dom.Document;
  2import org.w3c.dom.Element;
  3import org.w3c.dom.Node;
  4import org.w3c.dom.NodeList;
  5
  6import javax.xml.parsers.DocumentBuilder;
  7import javax.xml.parsers.DocumentBuilderFactory;
  8import javax.xml.transform.OutputKeys;
  9import javax.xml.transform.Transformer;
 10import javax.xml.transform.TransformerFactory;
 11import javax.xml.transform.dom.DOMSource;
 12import javax.xml.transform.stream.StreamResult;
 13import java.io.StringWriter;
 14import java.util.ArrayList;
 15import java.util.HashMap;
 16
 17public class XML {
 18    public static void main(String[] args) {
 19        // result list which contains all parsed rows
 20        ArrayList<HashMap<String, String>> result = new ArrayList<>();
 21        try {
 22            // create a factory
 23            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 24            // use the above factory to get a document builder
 25            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
 26            // use the document builder to parse the xml in the file 'data.xml'
 27            Document doc = documentBuilder.parse("data.xml");
 28
 29            // get the list of persons
 30            NodeList personList = doc.getElementsByTagName("person");
 31            // loop over the list of person
 32            for (int i = 0; i < personList.getLength(); i++) {
 33                // create a node out of the current item
 34                Node item = personList.item(i);
 35                // check if the node is an Element
 36                if (item.getNodeType() == Node.ELEMENT_NODE) {
 37                    // new hash map to contain the values of the row
 38                    HashMap<String, String> temp = new HashMap<>();
 39                    // put all values for the keys into the above map
 40                    temp.put("name", ((Element) item)
 41                        .getElementsByTagName("name")
 42                        .item(0)
 43                        .getTextContent());
 44
 45                    temp.put("surname", ((Element) item)
 46                        .getElementsByTagName("surname")
 47                        .item(0)
 48                        .getTextContent());
 49
 50                    temp.put("age", ((Element) item)
 51                        .getElementsByTagName("age")
 52                        .item(0)
 53                        .getTextContent());
 54
 55                    // add the row to the result list
 56                    result.add(tmap);
 57                }
 58           }
 59        } catch (Exception e) {
 60            // triggers if xml is invalid or the file cant be opened
 61            e.printStackTrace();
 62        }
 63        // print the list
 64        result.forEach(System.out::println);
 65
 66        try {
 67            // create a factory
 68            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 69            // use the factory to get a new document builder
 70            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
 71
 72            // use the document builder to get a new document
 73            Document doc = documentBuilder.newDocument();
 74
 75            // create the root element
 76            Element rootElement = doc.createElement("root");
 77            // append the root element to the document
 78            doc.appendChild(rootElement);
 79
 80            // loop over the maps in the result list
 81            for (HashMap<String, String> map : result) {
 82                // create a person element
 83                Element person = doc.createElement("person");
 84                // add the person element to the root element
 85                rootElement.appendChild(person);
 86
 87                // create elements and set their text content
 88                // to the value stored in the hash map
 89                Element name = doc.createElement("name");
 90                name.setTextContent(map.get("name"));
 91                person.appendChild(name);
 92
 93                Element surname = doc.createElement("surname");
 94                surname.setTextContent(map.get("surname"));
 95                person.appendChild(surname);
 96
 97                Element age = doc.createElement("age");
 98                age.setTextContent(map.get("age"));
 99                person.appendChild(age);
100            }
101
102            // get a new transformer factory
103            TransformerFactory transformerFactory = TransformerFactory.newInstance();
104            // use the factory to get a new Transformer
105            Transformer transformer = transformerFactory.newTransformer();
106
107            // instruct the transformer
108            // to add XML declaration at the top of the file
109            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
110            // instruct the transformer to indent the output
111            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
112
113            // get a new DOMSource from the document
114            DOMSource source = new DOMSource(doc);
115            // create a stringwriter to transform the source into
116            StringWriter stringWriter = new StringWriter();
117            transformer.transform(source, new StreamResult(stringWriter));
118
119            // print the output
120            System.out.println(stringWriter);
121        } catch (Exception e) {
122            e.printStackTrace();
123        }
124    }
125}

Running the above yields the following result:

 1{surname=Doe, name=John, age=45}
 2{surname=Doe, name=Jan, age=35}
 3<root>
 4    <person>
 5        <name>John</name>
 6        <surname>Doe</surname>
 7        <age>45</age>
 8    </person>
 9    <person>
10        <name>Jan</name>
11        <surname>Doe</surname>
12        <age>35</age>
13    </person>
14</root>

JSON ##

Json is the de facto standard data exchange and configuration standard. The whole JavaScript and Typescript ecosystem uses JSON to configure tools and send + receive data from REST APIS.

Danger

To parse json we us the org.json library. I wont discuss package / library managment in depth here, but the repo includes a guide for adding the library to your project.

Adding org.json to your project using gradle: ####

  • Add the following highlighted line to your build.gradle:
 1plugins {
 2    id 'java'
 3}
 4
 5group 'org.example'
 6version null
 7
 8repositories {
 9    mavenCentral()
10}
11
12dependencies {
13    implementation group: 'org.json', name: 'json', version: '20211205'
14}
  • Click on the green arrow next to the dependencies to download the dependency

Decoding ###

The example we want to parse into an ArrayList of hash maps is the following:

 1[
 2  {
 3    "name": "John",
 4    "surname": "Doe",
 5    "age": 45
 6  },
 7  {
 8    "name": "Jan",
 9    "surname": "Doe",
10    "age": 35
11  }
12]

Parsing a string to json is fairly easy while using the org.json library:

 1import java.io.BufferedReader;
 2import java.io.File;
 3import java.io.FileReader;
 4import java.util.ArrayList;
 5import java.util.HashMap;
 6import java.util.stream.Collectors;
 7
 8import org.json.*;
 9
10public class Main {
11    public static void main(String[] args) {
12        ArrayList<HashMap<String, String>> result = new ArrayList<>();
13        try{
14            // create a new file
15            File file = new File("data.json");
16            FileReader fileReader = new FileReader(file);
17            // read file with bufferedReader for better perf
18            BufferedReader bufferedReader = new BufferedReader(fileReader);
19            // read the lines and join them by "\n"
20            String fileContent = bufferedReader.lines().collect(Collectors.joining("\n"));
21
22            // use org.json.JSONArray to parse the string to a json object
23            JSONArray jsonArray = new JSONArray(fileContent);
24            // loop over every object in the array
25            for(int i = 0; i < jsonArray.length(); i++){
26                // create a new json object for every entry in the array
27                JSONObject o = jsonArray.getJSONObject(i);
28
29                // hash map to store row values
30                HashMap<String, String> temp = new HashMap<>();
31                // add values to keys
32                temp.put("name", o.getString("name"));
33                temp.put("surname", o.getString("surname"));
34                temp.put("age", String.valueOf(o.getInt("age")));
35
36                // add row to result
37                result.add(temp);
38            }
39        } catch (Exception e){
40            e.printStackTrace();
41        }
42
43        result.forEach(System.out::println);
44    }
45}

The above results in the same output as the parsing for CSV and XML:

1{surname=Doe, name=John, age=45}
2{surname=Doe, name=Jan, age=35}

Encoding ###

Encoding java objects into json is so easy it can be done in one loc:

 1import java.io.BufferedReader;
 2import java.io.File;
 3import java.io.FileReader;
 4import java.util.ArrayList;
 5import java.util.HashMap;
 6import java.util.stream.Collectors;
 7
 8import org.json.*;
 9
10public class Main {
11    public static void main(String[] args) {
12        ArrayList<HashMap<String, String>> result = new ArrayList<>();
13        try{
14            // create a new file
15            File file = new File("data.json");
16            FileReader fileReader = new FileReader(file);
17            // read file with bufferedReader for better perf
18            BufferedReader bufferedReader = new BufferedReader(fileReader);
19            // read the lines and join them by "\n"
20            String fileContent = bufferedReader
21                .lines()
22                .collect(Collectors.joining("\n"));
23
24            // use org.json.JSONArray to parse the string to a json object
25            JSONArray jsonArray = new JSONArray(fileContent);
26            // loop over every object in the array
27            for(int i = 0; i < jsonArray.length(); i++){
28                // create a new json object for every entry in the array
29                JSONObject o = jsonArray.getJSONObject(i);
30
31                // hash map to store row values
32                HashMap<String, String> temp = new HashMap<>();
33                // add values to keys
34                temp.put("name", o.getString("name"));
35                temp.put("surname", o.getString("surname"));
36                temp.put("age", String.valueOf(o.getInt("age")));
37
38                // add row to result
39                result.add(temp);
40            }
41        } catch (Exception e){
42            e.printStackTrace();
43        }
44
45        result.forEach(System.out::println);
46
47        System.out.println(new JSONArray(result).toString(4));
48    }
49}

The above results in:

 1{surname=Doe, name=John, age=45}
 2{surname=Doe, name=Jan, age=35}
 3[
 4    {
 5        "name": "John",
 6        "surname": "Doe",
 7        "age": "45"
 8    },
 9    {
10        "name": "Jan",
11        "surname": "Doe",
12        "age": "35"
13    }
14]