JAXB: Как маршалировать объекты в списках? - PullRequest
60 голосов
/ 10 сентября 2010

Возможно, глупый вопрос: у меня есть 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>

Это рекомендуемый способ создания структуры класса Java в соответствии с XMLструктура файла выше?

Ответы [ 3 ]

97 голосов
/ 10 сентября 2010

К записи добавить свойство:

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

Для получения дополнительной информации о JAXB и свойствах коллекции см .:

5 голосов
/ 10 сентября 2010

Это в ответ на ваш второй вопрос, на который нет ответа:

Оба подходасгенерирует тот же XML.Я рекомендую перейти на модель, которая лучше всего подходит для вашего приложения.Для меня это обычно использует @ XmlElementWrapper / @ XmlElement.Поскольку «записи» предназначены только для организации элементов «данных», на самом деле они не заслуживают своего собственного класса.

Я возглавляю реализацию MOXy JAXB , и мы предлагаем отображение на основе XPathрасширение, выходящее за пределы возможностей @XmlElementWrapper:

4 голосов
/ 07 августа 2012

В ответ на ваш второй вопрос:

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

Технически говоря, введение дополнительного класса Records для решения вашей проблемы JAXB является ненужной и избыточной работой, потому что JAXB не нуждается в этом. Свойства @XmlElementWrapper и @XmlElement name были разработаны для решения вашей проблемы.

Из ваших комментариев к ответу Блеза я веду учебник с примерами работы, объясняющими, как обращаться с общими классами, такими как List и т.

...