Convert JSON to XML Java using Gson and JAXB
โก Smart Summary
Convert JSON to XML Java using Gson and JAXB by mapping both formats onto the same annotated Java classes. This article defines each format, sets up the project, unmarshals XML with JAXB, writes JSON with Gson, and reverses the whole process.

What is JSON?
JSON is an abbreviation for JavaScript Object Notation, which is a data format that follows rules most programming languages can read. We can easily save it to a file or store it in a database. JSON format uses key-value pairs to describe data.
In the following example, we define a JSON string that stores personal information:
{
"username" : "guru99user",
"email" : "guru99user@mail.com"
}
So the syntax of JSON is very simple. Each item of data has two parts, a key and a value, which correspond to the field name and its value in a record. Looking further, there are a few rules like this:
- The JSON string is enclosed by curly braces {}.
- The keys of JSON must be enclosed in double quotation marks, and string values must be quoted as well.
- If there is more data (more key => value pairs), we use commas (,) to separate them.
- JSON keys should use plain letters, numbers, or the underscore character, with no spaces, and the first character should not be a number.
What is XML?
XML stands for eXtensible Markup Language, proposed by the World Wide Web Consortium (https://www.w3.org/) to create other markup languages. This is a simple subset that can describe many different types of data, so it is very useful for sharing data between systems.
Tags in XML are often not predefined, but they are created according to user conventions. XML introduces new features based on the advantages of HTML.
There are some useful XML features for diverse systems and solutions:
- XML is extensible: XML allows you to create your own custom tags to suit your application.
- XML carries data, it does not display it: XML allows you to store data regardless of how it will be displayed.
- XML is a common standard: XML was developed by the World Wide Web Consortium (W3C) and is available as an open standard.
XML is built on a nested node structure. Each node has an opening tag and a closing tag as follows:
<node>content</node>
In which:
- <node> is an open tag, and the name of this tag is defined by you.
- </node> is a closing tag, and the name of this tag must match the name of the open tag.
- content is the content of this tag.
At the top of each XML file you must declare a tag to indicate the XML version in use. The syntax of the instruction tag:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
JSON vs XML: Key Differences
Both formats carry structured data, and the table below shows why a project may need to move between them.
| Parameter | JSON | XML |
|---|---|---|
| Syntax style | Key and value pairs | Nested tags |
| Data types | String, number, boolean, null, array, object | Text only, types come from a schema |
| Attributes | Not supported | Supported on any element |
| Comments | Not supported | Supported |
| Verbosity | Compact | More verbose because tags repeat |
| Schema validation | JSON Schema, optional | DTD and XSD, mature |
| Typical use | Web APIs and configuration | Enterprise messaging and documents |
What is Gson?
Gson (https://github.com/google/gson) is a Java library that allows users to convert a Java object to a JSON string, and also to convert a JSON string back to a Java object. Gson can work with arbitrary Java objects, including existing objects whose source code you do not have.
Since version 1.6, Gson introduces two classes, JsonReader and JsonWriter, to provide streaming processing of JSON data.
- JsonWriter – Streaming write to JSON. We create a JsonWriter object. To start and finish creating a JSON object, we use the functions beginObject() and endObject(). Between those two calls, we write data as pairs (key => value).
JsonWriter writer = new JsonWriter();
writer.beginObject();
writer.name("key").value("value");
writer.endObject();
- JsonReader – Streaming read from JSON. We create a JsonReader object. To start and finish reading a JSON object, we use the functions beginObject() and endObject(). Between those two calls, we read data as pairs (key => value).
JsonReader reader = new JsonReader();
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("key")) {
String value = reader.nextString();
}
}
reader.endObject();
Gson streaming processing is fast. However, you need to handle each pair (key => value) of the JSON data yourself.
What is JAXB?
JAXB stands for Java Architecture for XML Binding, which is a library that uses annotations to convert Java objects to XML content and vice versa. As JAXB is defined by a specification, we can use different implementations of this standard.
With JAXB, we often use the following basic annotations:
- @XmlRootElement: This annotation specifies the outermost tag of the XML file, and it is therefore declared above a class.
- @XmlElementWrapper: This annotation creates a wrapper XML element around collections.
- @XmlElement: This annotation declares that a property of the object becomes a child tag of the XML file.
- @XmlAttribute: This annotation declares that a property of the object becomes an attribute on the surrounding tag.
The general implementation is as follows. First, we initialise the JAXBContext object with the MyObject class to convert.
JAXBContext jaxbContext = JAXBContext.newInstance(MyObject.class);
This JAXBContext object has a method that creates an object which converts XML content into a Java object, the Unmarshaller.
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
The same JAXBContext object also has a method that creates the object which converts a Java object into XML content, the Marshaller.
Marshaller marshallerObj = jaxbContext.createMarshaller();
โ ๏ธ Warning: JAXB was removed from the JDK in Java 11. On Java 11 and later, add the API and a runtime implementation to the project explicitly, for example jakarta.xml.bind:jakarta.xml.bind-api together with org.glassfish.jaxb:jaxb-runtime, and import the annotations from jakarta.xml.bind.annotation instead of javax.xml.bind.annotation.
How to convert XML to JSON?
We implement the example of XML to JSON conversion on the following platform. The versions below are the ones used for the screenshots. Newer releases of the JDK, Eclipse, and Gson work in the same way, subject to the JAXB note above.
- OpenJDK 8 for Ubuntu 18.04 x64.
- Eclipse IDE 2019-03 (4.11.0) x64 Java Development for Ubuntu.
- Gson 2.8.5.
Step 1) Create project.
Create a new Java project.
Step 2) Set project name.
Set the project name to XmlToJsonExample.
Step 3) Create a folder.
Create the folder data/input containing the two files sample.xml and sample.json.
Let us first define our XML with department, role, and person properties.
The general architecture is: one department has many roles, and one role has many persons. The diagram below shows those relationships.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <department> <roles> <role id="1"> <position>head</position> <salary>10k</salary> </role> <role id="2"> <position>manager</position> <salary>8k</salary> </role> <role id="3"> <position>employee</position> <salary>5k</salary> </role> </roles> <persons> <person id="1"> <name>Red</name> <role>1</role> </person> <person id="2"> <name>Green</name> <role>2</role> </person> <person id="3"> <name>Blue</name> <role>2</role> </person> <person id="4"> <name>Yellow</name> <role>3</role> </person> <person id="5"> <name>Brown</name> <role>3</role> </person> </persons> </department> </root>
Secondly, we define the JSON that expresses the same idea. Notice that the flat person list becomes a nested array inside each role, which is exactly the transformation the conversion code performs.
{
"roles": [
{
"id": "1",
"position": "head",
"salary": "10k",
"persons": [
{
"id": "1",
"name": "Red"
}
]
},
{
"id": "2",
"position": "manager",
"salary": "8k",
"persons": [
{
"id": "2",
"name": "Green"
},
{
"id": "3",
"name": "Blue"
}
]
},
{
"id": "3",
"position": "employee",
"salary": "5k",
"persons": [
{
"id": "4",
"name": "Yellow"
},
{
"id": "5",
"name": "Brown"
}
]
}
]
}
Step 4) Define objects.
Define the corresponding object classes in the package model.
Role.java
@XmlRootElement(name = "role") public class Role { private String id; private String position; private String salary; public Role() { super(); } public Role(String id, String position, String salary) { super(); this.id = id; this.position = position; this.salary = salary; } @XmlAttribute(name = "id") public String getId() { return id; } public void setId(String id) { this.id = id; } @XmlElement(name = "position") public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } @XmlElement(name = "salary") public String getSalary() { return salary; } public void setSalary(String salary) { this.salary = salary; } }
Person.java
@XmlRootElement(name = "person") public class Person { private String id; private String name; private String role; public Person() { super(); } public Person(String id, String name, String role) { super(); this.id = id; this.name = name; this.role = role; } @XmlAttribute(name = "id") public String getId() { return id; } public void setId(String id) { this.id = id; } @XmlElement(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } @XmlElement(name = "role") public String getRole() { return role; } public void setRole(String role) { this.role = role; } }
Department.java
@XmlRootElement(name = "department") public class Department { private List<Role> roles; private List<Person> persons; public Department() { super(); } public Department(List<Role> roles, List<Person> persons) { super(); this.roles = roles; this.persons = persons; } @XmlElementWrapper(name = "roles") @XmlElement(name = "role") public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } @XmlElementWrapper(name = "persons") @XmlElement(name = "person") public List<Person> getPersons() { return persons; } public void setPersons(List<Person> persons) { this.persons = persons; } }
XMLModel.java
@XmlRootElement(name = "root") public class XMLModel { private Department department; public XMLModel() { super(); } public XMLModel(Department department) { super(); this.department = department; } @XmlElement(name = "department") public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
Step 5) Set up the library.
Add and set up the Gson 2.8.5 library in the Java Build Path.
If the project uses Maven rather than a manually added jar, the same libraries are declared as dependencies. Version 2.8.5 is pinned here to match the screenshots, and any later Gson release works identically for this example:
<dependencies> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <!-- required on Java 11 and later --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> </dependency> </dependencies>
Convert XML message to Java objects using JAXB
Firstly, we define the performing classes in the package service.
At the first step of the first process, we use the un-marshalling technique of JAXB.
Un-marshalling provides a client application with the ability to convert XML data into JAXB derived Java objects.
We define the function getObjectFromXmlFile to un-marshal our XML file back into a Java object. This function is defined in the class XMLService.
public XMLModel getObjectFromXmlFile(String filePath) { try { File file = new File(filePath); JAXBContext jaxbContext = JAXBContext.newInstance(XMLModel.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); XMLModel root = (XMLModel) jaxbUnmarshaller.unmarshal(file); return root; } catch (JAXBException e) { e.printStackTrace(); return null; } }
We call the code above in the class XmlToJsonService.
XMLService xmlService = new XMLService(); XMLModel xmlModel = xmlService.getObjectFromXmlFile(filePathIn); Department department = xmlModel.getDepartment(); List<Role> roles = department.getRoles(); List<Person> persons = department.getPersons();
At this point the XML file has become three Java objects in memory. The next step writes them out as JSON.
Convert Java objects to JSON message using Gson
At this step, we define the function writeDataToJsonFile to write data to the JSON file. This function is defined in the class JsonService.
Note that to write a list of JSON objects, we use the functions beginArray() and endArray(). Between these two calls, we write each JSON object.
public void writeDataToJsonFile(String filePath, List<Role> roles, List<Person> persons) { try { JsonWriter writer = new JsonWriter(new FileWriter(filePath)); writer.setIndent(" "); writer.beginObject(); writer.name("roles"); writer.beginArray(); for (Role role : roles) { writer.beginObject(); writer.name("id").value(role.getId()); writer.name("position").value(role.getPosition()); writer.name("salary").value(role.getSalary()); writer.name("persons"); writer.beginArray(); for (Person person : persons) { if (person.getRole().equalsIgnoreCase(role.getId())) { writer.beginObject(); writer.name("id").value(person.getId()); writer.name("name").value(person.getName()); writer.endObject(); } } writer.endArray(); writer.endObject(); } writer.endArray(); writer.endObject(); writer.close(); } catch (IOException e) { } }
We call the above code in the class XmlToJsonService.
JsonService jsonService = new JsonService(); jsonService.writeDataToJsonFile(filePathOut, roles, persons);
That is the first process. The inner loop matches each person against the current role id, which is how the flat XML person list becomes a nested JSON array.
Convert JSON message to Java objects using Gson
At the first step of the second process, we define the function getDataFromJsonFile to read data from the JSON file. This function is defined in the class JsonService.
Note that to read a list of JSON objects, we use the functions beginArray() and endArray(). Between these two calls, we read each JSON object.
public void getDataFromJsonFile(String filePath, List<Role> roles, List<Person> persons) { try { JsonReader reader = new JsonReader(new FileReader(filePath)); reader.beginObject(); while (reader.hasNext()) { String nameRoot = reader.nextName(); if (nameRoot.equals("roles")) { reader.beginArray(); while (reader.hasNext()) { reader.beginObject(); Role role = new Role(); while (reader.hasNext()) { String nameRole = reader.nextName(); if (nameRole.equals("id")) { role.setId(reader.nextString()); } else if (nameRole.equals("position")) { role.setPosition(reader.nextString()); } else if (nameRole.equals("salary")) { role.setSalary(reader.nextString()); } else if (nameRole.equals("persons")) { reader.beginArray(); while (reader.hasNext()) { reader.beginObject(); Person person = new Person(); person.setRole(role.getId()); while (reader.hasNext()) { String namePerson = reader.nextName(); if (namePerson.equals("id")) { person.setId(reader.nextString()); } else if (namePerson.equals("name")) { person.setName(reader.nextString()); } } persons.add(person); reader.endObject(); } reader.endArray(); } } roles.add(role); reader.endObject(); } reader.endArray(); } } reader.endObject(); reader.close(); } catch (IOException e) { } }
We call the above code in the class XmlToJsonService.
JsonService jsonService = new JsonService(); List<Role> roles = new ArrayList<>(); List<Person> persons = new ArrayList<>(); jsonService.getDataFromJsonFile(filePathIn, roles, persons);
Convert Java objects to XML message using JAXB
At this step, we use the marshalling technique of JAXB.
Marshalling provides a client application with the ability to convert a JAXB derived Java object tree into XML data.
We define the function parseObjectToXml to marshal the Java object to an XML message. This function is defined in the class XMLService.
public void parseObjectToXml(String filePath, XMLModel xmlModel) { try { JAXBContext contextObj = JAXBContext.newInstance(XMLModel.class); Marshaller marshallerObj = contextObj.createMarshaller(); marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshallerObj.marshal(xmlModel, new FileOutputStream(filePath)); } catch (JAXBException je) { System.out.println("JAXBException"); } catch (IOException ie) { System.out.println("IOException"); } }
We call the above code in the class XmlToJsonService.
XMLService xmlService = new XMLService(); XMLModel xmlModel = new XMLModel(); Department department = new Department(); department.setRoles(roles); department.setPersons(persons); xmlModel.setDepartment(department); xmlService.parseObjectToXml(filePathOut, xmlModel);
That is the second process. The generated file matches the original sample.xml, which confirms that the round trip preserved every value.
How to Convert JSON to XML in Java without a Model Class?
The approach above is the right choice when the structure is known and stable, because the annotated classes document the contract. When the structure is unknown or changes often, a generic converter is quicker.
The org.json library performs the conversion in two lines, without any model class:
import org.json.JSONObject; import org.json.XML; public class QuickConverter { public static void main(String[] args) { String str = "{\"username\":\"guru99user\",\"email\":\"guru99user@mail.com\"}"; JSONObject json = new JSONObject(str); String xml = XML.toString(json); System.out.println(xml); } }
Output:
<username>guru99user</username><email>guru99user@mail.com</email>
Note that the generic route produces no root element and no attributes, so XML.toString(json, "root") is normally required. The table below sets the two approaches side by side.
| Criterion | Gson with JAXB | org.json generic conversion |
|---|---|---|
| Model classes required | Yes | No |
| Control over structure | Full, including attributes | Limited, elements only |
| Reshaping data | Possible, as shown with nested persons | Not possible |
| Lines of code | Many | Two |
| Best for | Stable, documented schemas | Ad hoc or unknown structures |
JAXB reads XML data and Gson writes it to JSON, and the reverse path uses Gson to read JSON data while JAXB writes it back to XML. To go further, review XML fundamentals, the wider Java tutorial, and JasperReports, which consumes both formats as report data sources.








