You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JAXB解析这类三级嵌套XML?

用JAXB解析三级嵌套XML的完整方案

我刚接触JAXB处理嵌套XML的时候也踩过不少坑,针对你这个三级结构的catalog XML,我整理了一套完整的实现步骤,保证你能快速跑通。

首先先明确你的XML层级:

<?xml version="1.0"?>
<catalog>
  <books>
    <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with XML.</description>
    </book>
    <book id="bk102">...</book>
  </books>
</catalog>

层级是:catalog(根)→ books(容器)→ book(重复子元素),每个book还有属性和子元素。


1. 创建对应的Java实体类

JAXB的核心是XML元素和Java类/字段的注解映射,我们需要从内到外创建三个实体类:Book、Books、Catalog。

1.1 最内层:Book类

对应XML里的<book>元素,注意id是属性,其他是子元素:

import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.util.Date;

@XmlAccessorType(XmlAccessType.FIELD) // 直接用字段映射,无需强制依赖getter/setter
public class Book {
    @XmlAttribute(name = "id") // 映射XML属性id
    private String id;
    
    @XmlElement(name = "author")
    private String author;
    
    @XmlElement(name = "title")
    private String title;
    
    @XmlElement(name = "genre")
    private String genre;
    
    @XmlElement(name = "price")
    private BigDecimal price;
    
    @XmlElement(name = "publish_date") // XML元素名是publish_date,对应Java字段publishDate
    private Date publishDate;
    
    @XmlElement(name = "description")
    private String description;

    // JAXB必须的无参构造器
    public Book() {}

    // 可选:添加带参构造器和getter/setter方便业务操作
    // ... 此处省略getter/setter代码,可自行生成
}

1.2 中间层:Books类

对应XML里的<books>容器,用来包裹多个<book>元素:

import javax.xml.bind.annotation.*;
import java.util.List;

@XmlAccessorType(XmlAccessType.FIELD)
public class Books {
    @XmlElement(name = "book") // 指定子元素为<book>,JAXB会自动将多个<book>映射为List
    private List<Book> bookList;

    public Books() {}

    // getter/setter
    public List<Book> getBookList() {
        return bookList;
    }

    public void setBookList(List<Book> bookList) {
        this.bookList = bookList;
    }
}

1.3 最外层:Catalog类

作为XML的根元素:

import javax.xml.bind.annotation.*;

@XmlRootElement(name = "catalog") // 指定根元素名称为catalog
@XmlAccessorType(XmlAccessType.FIELD)
public class Catalog {
    @XmlElement(name = "books") // 映射<books>子元素
    private Books books;

    public Catalog() {}

    // getter/setter
    public Books getBooks() {
        return books;
    }

    public void setBooks(Books books) {
        this.books = books;
    }
}

2. 编写解析代码

接下来用JAXB的API把XML文件转换成Java对象:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.File;

public class JAXBParserDemo {
    public static void main(String[] args) {
        try {
            // 1. 创建JAXB上下文,指定根类Catalog
            JAXBContext context = JAXBContext.newInstance(Catalog.class);
            
            // 2. 创建Unmarshaller(负责XML转Java对象)
            Unmarshaller unmarshaller = context.createUnmarshaller();
            
            // 3. 读取XML文件并解析成Catalog对象
            File xmlFile = new File("path/to/your/catalog.xml"); // 替换为你的XML文件路径
            Catalog catalog = (Catalog) unmarshaller.unmarshal(xmlFile);
            
            // 4. 验证解析结果:遍历所有book并打印信息
            catalog.getBooks().getBookList().forEach(book -> {
                System.out.println("Book ID: " + book.getId());
                System.out.println("Title: " + book.getTitle());
                System.out.println("Author: " + book.getAuthor());
                System.out.println("------------");
            });
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. 常见注意事项

  • 必须添加无参构造器:JAXB实例化对象时会调用无参构造,所有实体类都要有,否则会抛出解析异常。
  • 名称大小写严格匹配:XML里的元素/属性名称(比如publish_date)和注解里的name值必须完全一致,包括大小写。
  • 集合类型处理:如果有多个同类型子元素(比如多个<book>),一定要用List接收,并用@XmlElement(name="book")标注,JAXB会自动把所有<book>元素装进List。
  • 日期/数值类型:JAXB默认支持yyyy-MM-dd格式的字符串转Date,BigDecimal可以直接映射XML里的小数(比如44.95),如果有特殊格式,需要自定义XmlJavaTypeAdapter来处理。

内容的提问来源于stack exchange,提问作者kacmak7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:36:10