Peut-être une question stupide: j'ai un List
de type <Data>
que je veux rassembler dans un fichier XML. Ceci 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 voici 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; }
}
Utilisation de la classe de test suivante ...
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 toutes les balises pour <Data>
il manque des objets. Je cherche un moyen d'exporter les données dans la structure suivante, mais je ne sais pas comment y parvenir:
<database>
<records>
<data>
<address>Cologne</address>
<name>Peter</name>
</data>
<data>
<address>Hamburg</address>
<name>Mary</name>
</data>
</records>
</database>
Une question supplémentaire: si je veux résoudre le problème sans en utilisant @XmlElementWrapper
et @XmlElement
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 classe de base modifiée
@XmlRootElement
public class Database
{
Records records = new Records();
public Records getRecords() { return records; }
public void setRecords(Records records) { this.records = records; }
}
dans une classe Test
légèrement modifiée:
...
Database database = new Database();
database.getRecords().getData().add(data1);
database.getRecords().getData().add(data2);
...
Le résultat est également:
<database>
<records>
<data>
<address>Cologne</address>
<name>Peter</name>
</data>
<data>
<address>Hamburg</address>
<name>Mary</name>
</data>
</records>
</database>
Est-ce la manière recommandée de créer une structure de classe Java selon la structure de fichier XML ci-dessus?
Dans la propriété records, ajoutez:
@XmlElementWrapper(name="records")
@XmlElement(name="data")
Pour plus d'informations sur JAXB et les propriétés de collection, voir:
Ceci est en réponse à votre deuxième question a demandé une réponse:
Les deux approches généreront le même XML. Ma recommandation est d'aller avec le modèle qui convient le mieux à votre application. Pour moi, cela utilise généralement @ XmlElementWrapper/@ XmlElement. Puisque "records" est juste là pour organiser les éléments "data", il ne mérite pas vraiment sa propre classe.
Je dirige l'implémentation MOXy JAXB et nous proposons une extension de mappage basée sur XPath pour aller au-delà de ce qui est capable avec @XmlElementWrapper:
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'une classe Records
supplémentaire pour résoudre votre problème JAXB est un travail inutile et redondant, car JAXB n'en a pas besoin. Le @XmlElementWrapper
et @XmlElement
name
La propriété a été conçue pour résoudre votre problème.
De vos commentaires à la réponse de Blaise, je maintiens un tutoriel avec des exemples opérationnels expliquant comment faire face aux classes génériques telles que List, etc. lors du démarshalling.