Of course! Working with XML strings in Java is a common task. The best approach depends on your specific needs: parsing (reading) the XML, creating (writing) the XML, or transforming it.

Here’s a comprehensive guide covering the most popular methods in Java, from modern to classic.
Parsing (Reading) an XML String
This is the process of converting an XML string into a Java object model that you can easily navigate and manipulate.
Method A: The Modern & Recommended Approach - javax.xml.parsers (DOM & SAX)
This is the standard, built-in Java API for XML processing.
a) DOM (Document Object Model)
The DOM parser reads the entire XML document into memory and creates a tree-like structure. This is great for small to medium-sized XML files where you need to access data in any order.

Example: Parsing a simple XML string
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.ByteArrayInputStream;
public class DomParserExample {
public static void main(String[] args) {
String xmlString = "<employees>" +
" <employee id=\"101\">" +
" <name>Alice</name>" +
" <age>30</age>" +
" </employee>" +
" <employee id=\"102\">" +
" <name>Bob</name>" +
" <age>25</age>" +
" </employee>" +
"</employees>";
try {
// 1. Create a DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 2. Create a DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// 3. Parse the XML string
// We need to convert the String to an InputStream
Document document = builder.parse(new ByteArrayInputStream(xmlString.getBytes()));
// 4. Normalize the document structure
document.getDocumentElement().normalize();
// 5. Get all employee nodes
NodeList nodeList = document.getElementsByTagName("employee");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
// Get attributes
String id = element.getAttribute("id");
// Get child elements
NodeList nameNode = element.getElementsByTagName("name");
NodeList ageNode = element.getElementsByTagName("age");
String name = nameNode.item(0).getTextContent();
String age = ageNode.item(0).getTextContent();
System.out.println("Employee ID: " + id);
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("--------------------");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Pros:
- Easy to navigate the tree in any direction.
- Simple to modify the document in memory.
Cons:
- Loads the entire XML into memory, which can be slow and memory-intensive for large files.
b) SAX (Simple API for XML)
The SAX parser is an event-based parser. It reads the XML sequentially from top to bottom and triggers events (like startElement, endElement, characters) as it encounters different parts of the document. This is much more memory-efficient for large files.
Example: Parsing with SAX
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.ByteArrayInputStream;
public class SaxParserExample {
public static void main(String[] args) {
String xmlString = "<employees>" +
" <employee id=\"101\">" +
" <name>Alice</name>" +
" <age>30</age>" +
" </employee>" +
" <employee id=\"102\">" +
" <name>Bob</name>" +
" <age>25</age>" +
" </employee>" +
"</employees>";
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
// Define a custom handler to process the events
DefaultHandler handler = new DefaultHandler() {
boolean inEmployee = false;
boolean inName = false;
boolean inAge = false;
String currentId = "";
String currentName = "";
String currentAge = "";
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (qName.equalsIgnoreCase("employee")) {
inEmployee = true;
currentId = attributes.getValue("id");
} else if (qName.equalsIgnoreCase("name")) {
inName = true;
} else if (qName.equalsIgnoreCase("age")) {
inAge = true;
}
}
@Override
public void characters(char[] ch, int start, int length) {
if (inName) {
currentName = new String(ch, start, length);
}
if (inAge) {
currentAge = new String(ch, start, length);
}
}
@Override
public void endElement(String uri, String localName, String qName) {
if (qName.equalsIgnoreCase("employee")) {
inEmployee = false;
// Print the collected data for the employee
System.out.println("Employee ID: " + currentId);
System.out.println("Name: " + currentName);
System.out.println("Age: " + currentAge);
System.out.println("--------------------");
} else if (qName.equalsIgnoreCase("name")) {
inName = false;
} else if (qName.equalsIgnoreCase("age")) {
inAge = false;
}
}
};
saxParser.parse(new ByteArrayInputStream(xmlString.getBytes()), handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Pros:
- Very memory-efficient, as it doesn't load the whole document.
- Fast for large files.
Cons:
- Can only read the document sequentially (top to bottom).
- More complex to implement, as you have to manage state.
Method B: The Easiest Approach - Jackson (for JSON-like XML)
Jackson is a very popular library for JSON, but it also has excellent support for XML via the jackson-dataformat-xml module. It's incredibly simple if you just want to map XML directly to Java objects (POJOs).
Add the Jackson dependency to your project (Maven):
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.15.2</version> <!-- Use the latest version -->
</dependency>
Create Java classes to represent the XML structure:
// Root class
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List;
@JacksonXmlRootElement(localName = "employees")
public class Employees {
private List<Employee> employee;
public List<Employee> getEmployee() {
return employee;
}
public void setEmployee(List<Employee> employee) {
this.employee = employee;
}
}
// Employee class
public class Employee {
@JacksonXmlProperty(isAttribute = true, localName = "id")
private String id;
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlProperty(localName = "age")
private String age; // Can be int if you want to parse as number
// Getters and Setters
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getAge() { return age; }
public void setAge(String age) { this.age = age; }
}
Parse the XML string:
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class JacksonXmlParser {
public static void main(String[] args) {
String xmlString = "<employees>" +
" <employee id=\"101\">" +
" <name>Alice</name>" +
" <age>30</age>" +
" </employee>" +
" <employee id=\"102\">" +
" <name>Bob</name>" +
" <age>25</age>" +
" </employee>" +
"</employees>";
try {
XmlMapper xmlMapper = new XmlMapper();
Employees employees = xmlMapper.readValue(xmlString, Employees.class);
for (Employee emp : employees.getEmployee()) {
System.out.println("Employee ID: " + emp.getId());
System.out.println("Name: " + emp.getName());
System.out.println("Age: " + emp.getAge());
System.out.println("--------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Pros:
- Extremely simple and concise for mapping to objects.
- Handles complex nested structures well.
Cons:
- Requires an external library.
- Less control over low-level parsing details compared to SAX.
Creating (Writing) an XML String
Method A: Using javax.xml.transform (Recommended for Java)
This is the standard, modern way to create XML in Java.
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringWriter;
public class CreateXmlExample {
public static void main(String[] args) {
try {
// 1. Create a Document
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
// 2. Create the root element
Element rootElement = doc.createElement("bookstore");
doc.appendChild(rootElement);
// 3. Create child elements
Element book = doc.createElement("book");
book.setAttribute("category", "fiction");
rootElement.appendChild(book);
Element title = doc.createElement("title");
title.setTextContent("The Great Gatsby");
book.appendChild(title);
Element author = doc.createElement("author");
author.setTextContent("F. Scott Fitzgerald");
book.appendChild(author);
// 4. Use a Transformer to convert the Document to a String
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // Pretty print
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
String xmlString = writer.toString();
System.out.println(xmlString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Method B: Using Jackson (Very Easy)
If you're already using Jackson for parsing, it's just as easy to create XML.
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.util.ArrayList;
import java.util.List;
// Use the same Employee class from the Jackson parsing example
public class JacksonXmlCreator {
public static void main(String[] args) {
try {
XmlMapper xmlMapper = new XmlMapper();
// Create your Java objects
Employees employees = new Employees();
List<Employee> employeeList = new ArrayList<>();
Employee emp1 = new Employee();
emp1.setId("101");
emp1.setName("Alice");
emp1.setAge("30");
employeeList.add(emp1);
Employee emp2 = new Employee();
emp2.setId("102");
emp2.setName("Bob");
emp2.setAge("25");
employeeList.add(emp2);
employees.setEmployee(employeeList);
// Convert the Java object to an XML string
String xmlString = xmlMapper.writeValueAsString(employees);
System.out.println(xmlString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Summary: Which one should I use?
| Scenario | Recommended Method | Why? |
|---|---|---|
| Simple, small XML, need to access data randomly | DOM (javax.xml.parsers) |
It's built-in, easy to understand, and provides full navigation of the XML tree. |
| Large XML file, memory is a concern | SAX (javax.xml.parsers) |
It's event-based and uses very little memory, as it doesn't load the file into memory. |
| Just want to map XML to Java objects quickly | Jackson (jackson-dataformat-xml) |
It's incredibly simple, concise, and powerful. It's the de-facto choice for JSON/XML mapping. |
| Generating XML from Java objects | javax.xml.transform (DOM) or Jackson |
javax.xml.transform is the standard. Jackson is easier if you already have your POJOs set up. |
