JAXB:如何编组列表中的对象?
也许是一个愚蠢的问题:我有一个 类型的
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; }
}
...这是类 Data:
// @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>
但这不是我所期望的,即 对象的所有标签都丢失了。我正在寻找一种以以下结构导出数据的方法,但我不知道如何实现这一点:
<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 类结构的推荐方法吗?
Perhaps a stupid question: I have a List
of type <Data>
which I want to marshal into a XML file. This is my class Database
containing an 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; }
}
...and this is class Data:
// @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; }
}
Using the following test class...
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"));
}
}
...I got the result:
<database>
<records>
<address>Cologne</address>
<name>Peter</name>
</records>
<records>
<address>Hamburg</address>
<name>Mary</name>
</records>
</database>
But that's not what I was expecting, i.e. all tags for <Data>
objects are missing. I am looking for a way to export the data in the following structure, but I don't know how to achieve this:
<database>
<records>
<data>
<address>Cologne</address>
<name>Peter</name>
</data>
<data>
<address>Hamburg</address>
<name>Mary</name>
</data>
</records>
</database>
One additional question: if I want to deal with the problem without using @XmlElementWrapper
and @XmlElement
annotations, I can introduce an intermediary class
public class Records
{
List<Data> data = new ArrayList<Data>();
public List<Data> getData() { return data; }
public void setData(List<Data> data) { this.data = data; }
}
used by the modified base class
@XmlRootElement
public class Database
{
Records records = new Records();
public Records getRecords() { return records; }
public void setRecords(Records records) { this.records = records; }
}
in a slightly modified Test
class:
...
Database database = new Database();
database.getRecords().getData().add(data1);
database.getRecords().getData().add(data2);
...
The result also is:
<database>
<records>
<data>
<address>Cologne</address>
<name>Peter</name>
</data>
<data>
<address>Hamburg</address>
<name>Mary</name>
</data>
</records>
</database>
Is this the recommended way to create a Java class structure according to the XML file structure above?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在记录属性上添加:
有关 JAXB 和集合属性的更多信息,请参阅:
On the records property add:
For more information on JAXB and collection properties see:
这是对您的第二个问题的回应:
两种方法都会生成相同的 XML。我的建议是选择最适合您的应用的模型。对我来说,通常使用@XmlElementWrapper/@XmlElement。由于“记录”只是用来组织“数据”元素,因此它并不真正值得拥有自己的类。
我领导 MOXy JAXB 实现,我们提供基于 XPath 的映射扩展来超越@XmlElementWrapper 的功能:
This is in response to your second question disquised an answer:
Both approaches will generate the same XML. My recommendation is go with the model that is best for your application. For me that is generally using @XmlElementWrapper/@XmlElement. Since "records" is just there to organize the "data" elements it doesn't really deserve its own class.
I lead the MOXy JAXB implementation and we offer an XPath-based mapping extension to go beyond what is capable with @XmlElementWrapper:
回答你的第二个问题:
从技术上讲,引入额外的
Records
类来解决你的 JAXB 问题是不必要和多余的工作,因为 JAXB 不需要它。这@XmlElementWrapper
和@XmlElement
name
属性旨在解决您的问题。从您的评论到 Blaise 的回答,我维护了一个教程 带有操作示例,解释了在解组时如何处理 List 等通用类。
In response to your second question:
Technically speaking, introducing an extra
Records
class to solve your JAXB issue is unnecessary and redundant work, because JAXB does not need it. The@XmlElementWrapper
and@XmlElement
name
property have been designed to solve your issue.From your comments to Blaise's answer, I maintain a tutorial with operational examples explaining how do deal with generic classes such as List, etc.. when unmarshalling.