JAXB: Comment maréchal des objets dans les listes?
-
02-10-2019 - |
Question
Peut-être une question stupide: j'ai un List
de type <Data>
que je veux rassembler dans un fichier XML. Ceci est mon Database
de classe 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 la classe de données:
// @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 suivant ...
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"));
}
}
... Je suis le résultat:
<database>
<records>
<address>Cologne</address>
<name>Peter</name>
</records>
<records>
<address>Hamburg</address>
<name>Mary</name>
</records>
</database>
Mais ce ne est pas ce que j'attendais, à savoir tous les tags pour les objets de <Data>
manquent. 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égler le problème sans avec annotations @XmlElementWrapper
et @XmlElement
, 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ée 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:
<database>
<records>
<data>
<address>Cologne</address>
<name>Peter</name>
</data>
<data>
<address>Hamburg</address>
<name>Mary</name>
</data>
</records>
</database>
Est-ce le recommandé façon de créer une structure de classe Java selon la structure de fichier XML ci-dessus?
La solution
Sur les enregistrements ajouter la propriété:
@XmlElementWrapper(name="records")
@XmlElement(name="data")
Pour plus d'informations sur JAXB et propriétés de collection voir:
Autres conseils
Ceci est en réponse à votre deuxième question disquised une réponse:
Les deux approches va 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, qui utilise généralement @ XmlElementWrapper / @ XmlElement. Étant donné que des « documents » est juste là pour organiser les éléments « données » ne mérite pas vraiment sa propre classe.
Je dirige la mise en œuvre du Moxy JAXB et nous offre une extension de cartographie XPath d'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?
Sur le plan technique, l'introduction d'une classe Records
supplémentaire pour résoudre votre problème de JAXB est le travail inutile et redondant, parce que JAXB n'a pas besoin. le
propriété @XmlElementWrapper
et @XmlElement
name
ont été conçus 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 affaire avec des classes génériques telles que la liste, etc .. quand unmarshalling.