Convert XML to JSON Using Jackson

1. Overview

In this tutorial, we’ll see how to convert an XML message to JSON using Jackson.

For readers new to Jackson, consider getting familiar with the basics first.

2. An Introduction to Jackson

We can think about parsing JSON in three different ways with Jackson:

  • The first and most common is data binding with ObjectMapper
  • The second is mapping to a tree data structure with TreeTraversingParser and JsonNode
  • And the third is streaming the tree data structure by token, using JsonParser and JsonGenerator

Now, Jackson also supports the first two for XML data. As such, let’s see how Jackson can help us do the conversion from one format to the other.

3. Dependencies

First, we need to add the jackson-databind dependency to our pom.xml:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.1</version>
</dependency>

This library is going to allow us to use the data binding API.

The second is jackson-dataformat-xml which adds Jackson’s XML support:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.11.1</version>
</dependency>

4. Data Binding

Data binding, simply put, is when we want to map serialized data directly to a Java object.

To explore this, let’s define our XML with Flower and Color properties:

<Flower>
    <name>Poppy</name>
    <color>RED</color>
    <petals>9</petals>
</Flower>

This is similar to this Java notation:

public class Flower {
    private String name;
    private Color color;
    private Integer petals;
    // getters and setters
}

public enum Color { PINK, BLUE, YELLOW, RED; }

Our first step will be to parse the XML into a Flower instance. To do that, let’s create an instance of XmlMapper, Jackson’s XML equivalent for ObjectMapper and use its readValue method:

XmlMapper xmlMapper = new XmlMapper();
Flower poppy = xmlMapper.readValue(xml, Flower.class);

Once we have our Flower instance, we’ll want to write it out as JSON using the familiar ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(poppy);

And, as a result, we get our JSON equivalent:

{
    "name":"Poppy",
    "color":"RED",
    "petals":9
}

5. Tree Traversal

At times, looking directly at the tree structure can offer more flexibility, like in the case that we don’t want to maintain an intermediary class or we only want to convert a portion of the structure.

Though, as we’ll see, it comes with some tradeoffs.

The first step is similar to our first step when we use data binding. This time, though, we’ll use the readTree method:

XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xml.getBytes());

Having done this, we’ll have a JsonNode which has 3 children, as we expected: name, color, and petals.

Then, we can again use ObjectMapper, just sending our JsonNode instead:

ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);

Now, the outcome is slightly different compared to our last example:

{
    "name":"Poppy",
    "color":"RED",
    "petals":"9"
}

Upon careful inspection, we can see that the petals attribute is serialized into a string instead of a number! This is because readTree doesn’t infer the datatype without an explicit definition.

5.1. Limitations

And, there are certain limitations with Jackson’s XML tree traversal support:

  • Jackson cannot differentiate between an Object and an Array. Since XML lacks native structures to distinguish an object from a list of objects, Jackson will simply collate repeated elements into a single value.
  • And, since Jackson wants to map each XML element to a JSON node, it doesn’t support mixed content.

For these reasons, the official Jackson docs recommend against using Tree models to parse XML.

6. Memory Constraints

Now, both of these have the notable downside that the entire XML needs to be in memory at once in order to perform the conversion. Until Jackson supports streaming the tree structure as tokens, we’ll be stuck with this constraint or we’ll need to take a look at rolling our own with something like XMLStreamReader.

7. Conclusion

In this tutorial, we briefly learned different ways in which Jackson can read XML data and write it to JSON. Also, we took a quick look at the limitations of each supported approach.

As usual, the full source code that accompanies the tutorial is available over on GitHub.

Related posts:

Ignore Null Fields with Jackson
Java Program to Implement Binary Tree
Introduction to Netflix Archaius with Spring Cloud
Java Program to Perform Quick Sort on Large Number of Elements
Tạo chương trình Java đầu tiên sử dụng Eclipse
Java Program to Find the Peak Element of an Array O(n) time (Naive Method)
Java Program to Generate Random Hexadecimal Byte
Vấn đề Nhà sản xuất (Producer) – Người tiêu dùng (Consumer) và đồng bộ hóa các luồng trong Java
Java Program to Perform Left Rotation on a Binary Search Tree
Java Program to Implement Weight Balanced Tree
Java Program to Represent Graph Using Incidence List
Exploring the Spring 5 WebFlux URL Matching
Spring AMQP in Reactive Applications
Send email with authentication
Java Program to Implement Graham Scan Algorithm to Find the Convex Hull
Spring Security and OpenID Connect
Giới thiệu Google Guice – Aspect Oriented Programming (AOP)
Java Program to Solve TSP Using Minimum Spanning Trees
Feign – Tạo ứng dụng Java RESTful Client
Comparing Strings in Java
Java Web Services – JAX-WS – SOAP
Java Program to Generate a Random Subset by Coin Flipping
Java Program to Implement CopyOnWriteArrayList API
Spring JDBC
So sánh ArrayList và LinkedList trong Java
Spring Boot - Build Systems
Java Program to Implement Stack API
Java Program to Check Whether an Undirected Graph Contains a Eulerian Path
Converting String to Stream of chars
Giới thiệu về Stream API trong Java 8
Assert an Exception is Thrown in JUnit 4 and 5
Introduction to Eclipse Collections