如何使用JAXB将多个Book对象编组到同一XML文件中?
嘿,这个需求其实很好解决,核心就是给多个Book实例找一个「根容器」——毕竟XML要求必须有且仅有一个根元素,直接编组List会让JAXB摸不着头脑。我给你两种实用的实现方式,重点推荐第一种,规范又好维护:
方法一:创建一个Books容器类(推荐)
这种方式最通用,不管你有没有上层业务类,都能快速实现多Book的XML编组。我们只需要新建一个包含List<Book>的类,并用JAXB注解指定根元素和子元素的名称:
步骤1:编写Books容器类
package itemOrder; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import java.util.List; // 指定XML根元素名为books @XmlRootElement(name = "books") public class Books { private List<Book> bookList; // 指定每个List元素对应的XML标签为book @XmlElement(name = "book") public List<Book> getBookList() { return bookList; } public void setBookList(List<Book> bookList) { this.bookList = bookList; } }
步骤2:修改Main类实现多Book编组
在原来的基础上,我们只需要把多个Book实例放进List,再封装到Books对象里,然后正常编组即可:
package itemOrder; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import java.io.File; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { try { // 创建两本不同的Book实例 Book book1 = new Book(); book1.setId(1); book1.setTitle("Java编程思想"); book1.setAuthor("Bruce Eckel"); book1.setPrice(79.9); Book book2 = new Book(); book2.setId(2); book2.setTitle("Effective Java"); book2.setAuthor("Joshua Bloch"); book2.setPrice(89.0); // 将Book实例存入List,再封装到Books容器 List<Book> bookList = new ArrayList<>(); bookList.add(book1); bookList.add(book2); Books books = new Books(); books.setBookList(bookList); // 初始化JAXB上下文,注意要包含Books和Book两个类 JAXBContext context = JAXBContext.newInstance(Books.class, Book.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 格式化XML输出,方便阅读 // 编组到指定XML文件 marshaller.marshal(books, new File("books.xml")); // 同时输出到控制台查看结果 marshaller.marshal(books, System.out); } catch (JAXBException e) { e.printStackTrace(); } } }
最终生成的XML结构
运行后你会得到结构清晰的XML文件,完全符合规范:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <books> <book> <id>1</id> <title>Java编程思想</title> <author>Bruce Eckel</author> <price>79.9</price> </book> <book> <id>2</id> <title>Effective Java</title> <author>Joshua Bloch</author> <price>89.0</price> </book> </books>
方法二:利用@XmlElementWrapper(适用于已有上层业务类的场景)
如果你的业务场景里已经有一个上层类(比如Order订单类),需要在订单里包含多本书,那可以直接在该类的List<Book>字段上添加@XmlElementWrapper注解,自动生成包裹节点:
package itemOrder; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import java.util.List; @XmlRootElement(name = "order") public class Order { private int orderId; // 用XmlElementWrapper指定包裹节点名为books,XmlElement指定子节点为book @XmlElementWrapper(name = "books") @XmlElement(name = "book") private List<Book> books; // 省略getter和setter方法 }
这种方式不需要新建容器类,直接复用现有业务类即可完成多Book的编组。
内容的提问来源于stack exchange,提问作者FirkaPirka
相关产品推荐
相关产品推荐

