JAXB:如何编组列表中的对象?
Posted
技术标签:
【中文标题】JAXB:如何编组列表中的对象?【英文标题】:JAXB: How to marshal objects in lists? 【发布时间】:2011-04-10 15:52:38 【问题描述】:也许是个愚蠢的问题:我有一个 <Data>
类型的 List
,我想将其编组为 XML 文件。这是我的课程Database
,其中包含一个ArrayList
...
@XmlRootElement
public class Database
List<Data> records = new ArrayList<Data>();
public List<Data> getRecords() return records;
public void setRecords(List<Data> records) this.records = records;
...这是数据类:
// @XmlRootElement
public class Data
String name;
String address;
public String getName() return name;
public void setName(String name) this.name = name;
public String getAddress() return address;
public void setAddress(String address) this.address = address;
使用下面的测试类...
public class Test
public static void main(String args[]) throws Exception
Data data1 = new Data();
data1.setName("Peter");
data1.setAddress("Cologne");
Data data2 = new Data();
data2.setName("Mary");
data2.setAddress("Hamburg");
Database database = new Database();
database.getRecords().add(data1);
database.getRecords().add(data2);
JAXBContext context = JAXBContext.newInstance(Database.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(database, new FileWriter("test.xml"));
...我得到了结果:
<database>
<records>
<address>Cologne</address>
<name>Peter</name>
</records>
<records>
<address>Hamburg</address>
<name>Mary</name>
</records>
</database>
但这不是我所期望的,即<Data>
对象的所有标签都丢失了。我正在寻找一种以以下结构导出数据的方法,但我不知道如何实现:
<database>
<records>
<data>
<address>Cologne</address>
<name>Peter</name>
</data>
<data>
<address>Hamburg</address>
<name>Mary</name>
</data>
</records>
</database>
另外一个问题:如果我想不使用@XmlElementWrapper
和@XmlElement
注解来处理这个问题,我可以引入一个中间类
public class Records
List<Data> data = new ArrayList<Data>();
public List<Data> getData() return data;
public void setData(List<Data> data) this.data = data;
被修改后的基类使用
@XmlRootElement
public class Database
Records records = new Records();
public Records getRecords() return records;
public void setRecords(Records records) this.records = records;
在稍作修改的Test
类中:
...
Database database = new Database();
database.getRecords().getData().add(data1);
database.getRecords().getData().add(data2);
...
结果也是:
<database>
<records>
<data>
<address>Cologne</address>
<name>Peter</name>
</data>
<data>
<address>Hamburg</address>
<name>Mary</name>
</data>
</records>
</database>
这就是推荐按照上面的XML文件结构创建Java类结构的方式吗?
【问题讨论】:
我没有看到你在测试类中使用DataList
。
对不起 - 我复制并粘贴了错误的类...现在在上面的示例中更正了。
Using JAXB to unmarshal/marshal a List<String>的可能重复
【参考方案1】:
在记录属性上添加:
@XmlElementWrapper(name="records")
@XmlElement(name="data")
有关 JAXB 和集合属性的更多信息,请参阅:
JAXB & Collection Properties【讨论】:
酷,就是这样!非常感谢。 @LawrenceTierney -@XmlAccessorType
上的以下文章可能有助于注释字段或属性(getter/setter):blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
@XmlelementWrapper 不适用于类型 - 编译错误消息。怎么了?【参考方案2】:
这是对你第二个问题的回答:
JAXB: How to marshal objects in lists?两种方法都将生成相同的 XML。我的建议是使用最适合您的应用程序的模型。对我来说,这通常使用@XmlElementWrapper/@XmlElement。由于“记录”只是用来组织“数据”元素,因此它并不真正值得拥有自己的类。
我领导 MOXy JAXB 的实现,我们提供了一个基于 XPath 的映射扩展,以超越 @XmlElementWrapper 的能力:
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html【讨论】:
这个领域正在发生的事情真的令人印象深刻。我想我需要一些时间来接触这种新的映射技术。能否给我第一个提示,如何将导出的 XML 数据再次读入类结构?如果我使用@XmlElementWrapper/@XmlElement 进行导出,导入程序会抱怨相应的类(显然:-) 不存在... 导入(解组)应该可以正常工作,您遇到什么异常? 我想我遇到了一个异常,即找不到类“记录”。但可以肯定的是,我明天会通过一个例子来验证它...... 是的,你是对的,解组按预期工作! --- JAXBContext 上下文 = JAXBContext.newInstance(Database.class);解组器 unmarshaller = context.createUnmarshaller();数据库数据库 = (Database) unmarshaller.unmarshal(new File("test.xml")); 我会在你的博客上发布这个,但似乎只有团队成员可以在那里回复。感谢您的示例代码,但是在 2017 年,现在有没有更简洁的方法可以在没有样板类和严格类型的情况下执行此操作?【参考方案3】:回答你的第二个问题:
Is this the recommended way to create a Java class structure
according to the XML file structure above?
从技术上讲,引入一个额外的Records
类来解决您的 JAXB 问题是不必要且多余的工作,因为 JAXB 不需要它。这
@XmlElementWrapper
和 @XmlElement
name
属性旨在解决您的问题。
从您的 cmets 到 Blaise 的回答,我维护了一个 tutorial,其中包含操作示例,解释了在解组时如何处理 List 等泛型类。
【讨论】:
以上是关于JAXB:如何编组列表中的对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 JAXB 对象编组到 org.w3c.dom.Document?
带有 java.lang.Object 字段的 JAXB 编组对象