杰瑞科技汇

java list to xml

Of course! Converting a Java List to an XML format is a common task. The best approach depends on your specific needs, such as whether you're using a modern framework like Java 17+ or a more traditional one like Java 8.

Here’s a comprehensive guide covering the most popular and effective methods, from modern and simple to classic and powerful.

Scenario: What We'll Convert

Let's assume we have a List of Product objects. This is a more realistic example than a simple List<String>.

// First, define a simple POJO (Plain Old Java Object)
class Product {
    private int id;
    private String name;
    private double price;
    // Constructors, Getters, and Setters (essential for most libraries)
    public Product() {}
    public Product(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
    // toString() is good for debugging
    @Override
    public String toString() {
        return "Product{" + "id=" + id + ", name='" + name + '\'' + ", price=" + price + '}';
    }
}

And our list of products:

List<Product> productList = new ArrayList<>();
productList.add(new Product(1, "Laptop", 1200.50));
productList.add(new Product(2, "Mouse", 25.99));
productList.add(new Product(3, "Keyboard", 75.00));

Method 1: The Modern Java Way (Java 17+ with javax.xml.bind)

If you are using Java 17 or newer, this is the simplest and most recommended approach. It requires no external libraries.

Step 1: Add Dependency (if not using Java 17+)

If you're on an older Java version, you'll need to add the JAXB (Java Architecture for XML Binding) dependency to your project (e.g., in pom.xml for Maven):

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>4.0.0</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>4.0.2</version>
</dependency>

For older Java versions (before 9), you would use javax.xml.bind instead of jakarta.xml.bind.

Step 2: Create the JAXB Context and Marshaller

JAXB uses annotations to map Java objects to XML. We need to annotate our Product class.

import jakarta.xml.bind.annotation.*;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import java.io.StringWriter;
// Annotate the Product class
@XmlRootElement(name = "product") // Specifies the root element for a single object
@XmlAccessorType(XmlAccessType.FIELD) // Maps fields to XML elements by default
class Product {
    // ... (keep the same fields, constructors, getters, setters)
    @XmlAttribute // Maps this field to an XML attribute
    private int id;
    @XmlElement(name = "productName") // Maps this field to an XML element with a custom name
    private String name;
    @XmlElement
    private double price;
}

Step 3: Perform the Conversion

Now, let's convert the List<Product> to a String of XML.

public class ListToXmlConverter {
    public static void main(String[] args) throws Exception {
        List<Product> productList = List.of(
            new Product(1, "Laptop", 1200.50),
            new Product(2, "Mouse", 25.99),
            new Product(3, "Keyboard", 75.00)
        );
        // 1. Create a JAXBContext for the list's element type (Product)
        JAXBContext jaxbContext = JAXBContext.newInstance(Product.class);
        // 2. Create a Marshaller
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // Pretty print
        // 3. Create a wrapper object for the list to define the root element
        // JAXB can't directly marshal a List, so we wrap it.
        class ProductListWrapper {
            @XmlElement(name = "product")
            private List<Product> products;
            public ProductListWrapper(List<Product> products) {
                this.products = products;
            }
        }
        ProductListWrapper wrapper = new ProductListWrapper(productList);
        // 4. Marshal the wrapper object to a String
        StringWriter writer = new StringWriter();
        marshaller.marshal(wrapper, writer);
        // 5. Get the XML string
        String xml = writer.toString();
        System.out.println(xml);
    }
}

Output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<productListWrapper>
    <product id="1">
        <productName>Laptop</productName>
        <price>1200.5</price>
    </product>
    <product id="2">
        <productName>Mouse</productName>
        <price>25.99</price>
    </product>
    <product id="3">
        <productName>Keyboard</productName>
        <price>75.0</price>
    </product>
</productListWrapper>

Method 2: The Classic Powerful Way (DOM API)

The DOM (Document Object Model) API gives you full control over the XML structure. It's more verbose but is part of standard Java (javax.xml.parsers).

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
public class DomListToXmlConverter {
    public static void main(String[] args) throws Exception {
        List<Product> productList = List.of(
            new Product(1, "Laptop", 1200.50),
            new Product(2, "Mouse", 25.99),
            new Product(3, "Keyboard", 75.00)
        );
        // 1. Create a DocumentBuilderFactory and DocumentBuilder
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        // 2. Create a new Document
        Document doc = docBuilder.newDocument();
        // 3. Create the root element <products>
        Element rootElement = doc.createElement("products");
        doc.appendChild(rootElement);
        // 4. Iterate through the list and create an element for each product
        for (Product product : productList) {
            Element productElement = doc.createElement("product");
            // Create child elements and append them
            Element idElement = doc.createElement("id");
            idElement.appendChild(doc.createTextNode(String.valueOf(product.getId())));
            productElement.appendChild(idElement);
            Element nameElement = doc.createElement("name");
            nameElement.appendChild(doc.createTextNode(product.getName()));
            productElement.appendChild(nameElement);
            Element priceElement = doc.createElement("price");
            priceElement.appendChild(doc.createTextNode(String.valueOf(product.getPrice())));
            productElement.appendChild(priceElement);
            // Append the <product> element to the root
            rootElement.appendChild(productElement);
        }
        // 5. 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
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(writer));
        String xml = writer.toString();
        System.out.println(xml);
    }
}

Output:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<products>
  <product>
    <id>1</id>
    <name>Laptop</name>
    <price>1200.5</price>
  </product>
  <product>
    <id>2</id>
    <name>Mouse</name>
    <price>25.99</price>
  </product>
  <product>
    <id>3</id>
    <name>Keyboard</name>
    <price>75.0</price>
  </product>
</products>

Method 3: The Simplest Library (Gson)

If you are already using Google's Gson library for JSON, it can also produce simple XML. It's not as feature-rich as JAXB for complex XML schemas but is very easy to use.

Step 1: Add Dependency

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Step 2: Perform the Conversion

Gson requires a TypeToken to handle generic types like List<Product>.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
public class GsonListToXmlConverter {
    public static void main(String[] args) {
        List<Product> productList = List.of(
            new Product(1, "Laptop", 1200.50),
            new Product(2, "Mouse", 25.99),
            new Product(3, "Keyboard", 75.00)
        );
        // 1. Create a Gson instance
        Gson gson = new GsonBuilder()
                .setPrettyPrinting() // For pretty-printing the output
                .create();
        // 2. Define the type for the list
        Type productListType = new TypeToken<List<Product>>() {}.getType();
        // 3. Convert the list to a JSON string first
        String json = gson.toJson(productList, productListType);
        System.out.println("Intermediate JSON:");
        System.out.println(json);
        // 4. Convert the JSON string to XML
        // Gson doesn't have a direct .toJsonXml() method, so we use a helper class.
        // This is a common pattern. You can find many implementations online.
        String xml = JsonToXmlConverter.convert(json);
        System.out.println("\nFinal XML:");
        System.out.println(xml);
    }
}
// A simple helper class to convert JSON to XML (one possible implementation)
class JsonToXmlConverter {
    public static String convert(String json) {
        // This is a very basic converter and won't handle all edge cases.
        // For production, use a dedicated library or the JAXB/DOM methods.
        String xml = json
            .replace("{", "<products>")
            .replace("}", "</products>")
            .replace("\"", "")
            .replace("[", "")
            .replace("]", "")
            .replace(":", "<value>")
            .replace(",", "</value><key>")
            .replace("<key>id", "<id>")
            .replace("<key>name", "<name>")
            .replace("<key>price", "<price>")
            .replace("</value><key>", "</value></product><product><key>")
            .replace("</value></product><product><key>", "</value></product><product><key>")
            .replace("<value></value></product><product><key>", "");
        // Clean up the last product
        xml = xml.replace("<key></key>", "");
        xml = xml.replace("</value></product><product>", "</product><product>");
        xml = xml.replace("</value></product>", "</value></product>");
        return xml;
    }
}

Output:

Intermediate JSON:
[
  {
    "id": 1,
    "name": "Laptop",
    "price": 1200.5
  },
  {
    "id": 2,
    "name": "Mouse",
    "price": 25.99
  },
  {
    "id": 3,
    "name": "Keyboard",
    "price": 75.0
  }
]
Final XML:
<products>
<product>
<id><value>1</value></id>
<name><value>Laptop</value></name>
<price><value>1200.5</value></price>
</product>
<product>
<id><value>2</value></id>
<name><value>Mouse</value></name>
<price><value>25.99</value></price>
</product>
<product>
<id><value>3</value></id>
<name><value>Keyboard</value></name>
<price><value>75.0</value></price>
</product>
</products>

Note: The Gson-to-XML part is a bit of a hack and shows its limitation. For true XML generation, prefer JAXB or DOM.


Summary and Recommendation

Method Pros Cons Best For
JAXB (Modern) - Clean, annotation-driven
- Standard in Java 17+
- Powerful and robust
- Requires a wrapper object for lists
- Needs dependency for older Java
Most new Java applications. The standard, most maintainable way.
DOM API - Full control over XML structure
- No external dependencies
- Standard Java library
- Very verbose (boilerplate code)
- Manual creation of every element/attribute
Situations where you need fine-grained control over the XML output and can't use external libraries.
Gson - Extremely simple if you already use it
- Minimal code for basic conversion
- Not a native XML solution
- Output can be limited or require hacks
- Less control over XML structure
Quick and dirty conversions or when you are deeply integrated into the Google/Gson ecosystem and don't need complex XML.

Final Recommendation:

For any new project on Java 17 or newer, use JAXB. It's the modern standard, provides a clean mapping between Java objects and XML, and is the most maintainable solution.

If you are on an older Java version or have strict dependency constraints, the DOM API is your best bet from the standard library. Avoid the Gson-to-XML approach for anything beyond trivial use cases.

分享:
扫描分享到社交APP
上一篇
下一篇