如何使用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
相关产品推荐
相关产品推荐

