如何基于Java对象生成指定格式的XML文件?已尝试JAXB但格式不符
解决JAXB生成指定XML格式的问题
要生成你需要的XML结构,得从三个方面调整代码:创建根容器类、修改实体类的注解配置、调整序列化逻辑,具体步骤如下:
1. 创建根元素对应的容器类
因为你需要根元素<persons>包裹所有<person>,所以要定义一个专门的类来承载这个列表:
import javax.xml.bind.annotation.XmlRootElement; import java.util.List; @XmlRootElement(name = "persons") public class Persons { private List<Person> person; public List<Person> getPerson() { return person; } public void setPerson(List<Person> person) { this.person = person; } }
2. 修改Person实体类的注解配置
把原来的字段改成属性形式,用@XmlAttribute注解替代默认的子元素映射:
import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "person") public class Person { private String name; private String birthday; private String surname; // 可选字段 // JAXB要求必须有无参构造 public Person() {} public Person(String name, String birthday) { this.name = name; this.birthday = birthday; } public Person(String surname, String name, String birthday) { this.surname = surname; this.name = name; this.birthday = birthday; } @XmlAttribute public String getName() { return name; } public void setName(String name) { this.name = name; } @XmlAttribute public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } @XmlAttribute(required = false) // 标记为可选属性 public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } }
3. 调整序列化逻辑
原来的循环marshal会覆盖文件,而且没有根元素,现在直接序列化根容器对象:
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import java.io.File; import java.util.List; public class XmlGenerator { public static void createNewXml(List<Person> persons) { // 将列表封装到根容器 Persons root = new Persons(); root.setPerson(persons); try { // 注意这里要传入根容器类Persons JAXBContext jaxbContext = JAXBContext.newInstance(Persons.class); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); File file = new File("personx.xml"); marshaller.marshal(root, file); } catch (JAXBException e) { throw new RuntimeException(e); } } }
最终生成的XML结构
运行后会得到符合预期的格式:
<persons> <person name="aaa Sd" birthday="09.03.1814"/> <person surname="Smith" name="John" birthday="15.07.1990"/> </persons>
原代码的问题说明
- 缺少根容器类,无法生成
<persons>根元素 - 实体类字段默认映射为XML子元素,而非属性
- 循环调用
marshal会多次写入文件,最终仅保留最后一个对象的内容
内容的提问来源于stack exchange,提问作者Dudka Dima
相关产品推荐
相关产品推荐

