61 votes

JAXB: Comment annuler les objets dans les listes?

Peut-être une question bête: j'ai un List de type <Data> qui je veux unmarshall dans un fichier XML. C'est ma classe, Database contenant un 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; }
}

...et c'est les Données de la classe:

// @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; }
}

À l'aide de la suite de test de la classe...

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"));       
    }
}

...J'ai obtenu le résultat:

<database>
    <records>
        <address>Cologne</address>
        <name>Peter</name>
    </records>
    <records>
        <address>Hamburg</address>
        <name>Mary</name>
    </records>
</database>

Mais ce n'est pas ce que j'attendais, c'est à dire tous les tags pour <Data> des objets sont manquants. Je suis à la recherche d'un moyen d'exporter les données dans la structure suivante, mais je ne sais pas comment faire pour y parvenir:

<database>
    <records>
        <data>
            <address>Cologne</address>
            <name>Peter</name>
        </data>
        <data>
            <address>Hamburg</address>
            <name>Mary</name>
        </data>
    </records>
</database>

Une autre question: si je veux régler le problème sans l'aide d' @XmlElementWrapper et @XmlElement des annotations, je peux introduire une classe intermédiaire

public class Records
{
    List<Data> data = new ArrayList<Data>();

    public List<Data> getData()                { return data; }
    public void       setData(List<Data> data) { this.data = data; }
}

utilisé par la modification de la classe de base

@XmlRootElement
public class Database
{
    Records records = new Records();

    public Records getRecords()                { return records; }
    public void    setRecords(Records records) { this.records = records; }
}

légèrement modifiés Test classe:

...
Database database = new Database();
database.getRecords().getData().add(data1);
database.getRecords().getData().add(data2);
...

Le résultat est aussi:

<database>
    <records>
        <data>
            <address>Cologne</address>
            <name>Peter</name>
        </data>
        <data>
            <address>Hamburg</address>
            <name>Mary</name>
        </data>
    </records>
</database>

Est-ce recommandé de créer une classe Java en fonction de la structure la structure du fichier XML ci-dessus?

100voto

Blaise Doughan Points 75613

Sur la propriété records, ajoutez:

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

Pour plus d'informations sur JAXB et les propriétés de la collection, voir:

5voto

Blaise Doughan Points 75613

C'est en réponse à votre deuxième question disquised une réponse:

Les deux approches permettra de générer le même XML. Ma recommandation est d'aller avec le modèle qui est le mieux pour votre application. Pour moi, c'est généralement à l'aide de @XmlElementWrapper/@XmlElement. Depuis "dossiers" est juste là pour organiser les "données" éléments qu'il ne mérite pas sa propre classe.

Je dirige la MOXy JAXB la mise en œuvre et nous offre un chemin XPath de cartographie sur l'extension à aller au-delà de ce qu'est capable avec @XmlElementWrapper:

4voto

JVerstry Points 12414

En réponse à votre deuxième question:

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

Techniquement parlant, l'introduction d'un extra - Records classe pour résoudre vos JAXB question est inutile et redondant de travail, parce que JAXB n'en a pas besoin. L' @XmlElementWrapper et @XmlElement name des biens ont été conçus pour résoudre votre problème.

Vos commentaires de Blaise de réponse, je maintiens un tutoriel avec des exemples de fonctionnement expliquant comment traiter avec les classes génériques tels que les listes, etc.. quand unmarshalling.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X