JAXB:如何编组列表中的对象?

时间:2010-09-10 09:43:10

标签: xml jaxb arraylist unmarshalling

也许是一个愚蠢的问题:我有List类型<Data>,我希望将其编组到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类结构吗?

3 个答案:

答案 0 :(得分:96)

在记录属性上添加:

@XmlElementWrapper(name="records")
@XmlElement(name="data")

有关JAXB和集合属性的更多信息,请参阅:

答案 1 :(得分:5)

这是对你的第二个问题的回答:

两种方法都会生成相同的XML。我的建议是使用最适合您应用的模型。对我来说,通常使用@ XmlElementWrapper / @ XmlElement。由于“记录”只是用于组织“数据”元素,因此它并不值得拥有自己的类。

我领导MOXy JAXB实现,我们提供基于XPath的映射扩展,超越了@XmlElementWrapper的功能:

答案 2 :(得分:4)

回答你的第二个问题:

Is this the recommended way to create a Java class structure
according to the XML file structure above?

从技术上讲,引入一个额外的Records类来解决您的JAXB问题是不必要的冗余工作,因为JAXB不需要它。该 @XmlElementWrapper@XmlElement name属性旨在解决您的问题。

从你的评论到Blaise的回答,我保留了一个tutorial的操作示例,解释了在解组时如何处理List等通用类。