Jackson. Serialitzant XML
En el desenvolupament d’aplicacions Java, és comú treballar amb dades en format XML. A través de la llibreria Jackson, que és àmpliament coneguda pel seu suport per a JSON, també es poden gestionar documents XML
de manera senzilla utilitzant la classe XmlMapper
. Aquesta classe permet convertir objectes Java a XML (serialització) i convertir XML a objectes Java (deserialització).
XmlMapper
XmlMapper
és una classe proporcionada pel mòdul jackson-dataformat-xml
que permet treballar amb XML de manera similar a com es fa amb JSON a través de ObjectMapper
. Aquesta classe és útil per gestionar dades que es reben o s’envien en format XML, un format de dades estructurat que és utilitzat sovint en aplicacions empresarials, configuracions i serveis web.
Mètodes de XmlMapper
La classe XmlMapper
ofereix diversos mètodes per treballar amb XML i mapejar-lo a objectes Java i viceversa. A continuació es descriuen els mètodes més importants:
Mètode | Descripció |
---|---|
readValue() | Deserialitza un contingut XML en un objecte Java. Pot llegir des d’una cadena (String), un fitxer, o un InputStream . |
writeValue() | Serialitza un objecte Java en un contingut XML. Pot escriure a una cadena (String), un fitxer o un OutputStream . |
readTree() | Llegeix un contingut XML com a JsonNode , una representació abstracta de les dades, útil per explorar dades XML sense mapar-les a classes concretes. |
writeTree() | Escriu un JsonNode com a contingut XML. |
readValues() | Llegeix una seqüència de documents XML separats. |
readerForUpdating() | Permet l’actualització incremental d’un objecte Java existent amb dades XML. |
getFactory() | Obté l’objecte JsonFactory associat amb l’XmlMapper . Es pot configurar per gestionar aspectes específics com l’ús de DTDs, espais de noms, etc. |
getSerializationConfig() | Obté la configuració de serialització per personalitzar aspectes com la indentació o la inclusió d’espais de noms XML. |
getDeserializationConfig() | Obté la configuració de deserialització per gestionar opcions específiques de l’anàlisi XML, com reconèixer espais de noms o CDATA. |
setConfig() | Configura l’objecte XmlMapper amb una nova configuració personalitzada per a gestionar opcions específiques de l’anàlisi o la generació d’XML. |
Exemples d’ús de XmlMapper
- Deserialització d’XML en un objecte Java:
XmlMapper xmlMapper = new XmlMapper(); String xmlString = "<persona><nom>John</nom><edat>30</edat></persona>"; Persona persona = xmlMapper.readValue(xmlString, Persona.class);
Utilitzem
readValue()
per convertir un fragment d’XML en un objecte Java de la classePersona
. - Serialització d’un objecte Java a XML:
XmlMapper xmlMapper = new XmlMapper(); Persona persona = new Persona("John", 30); String xmlString = xmlMapper.writeValueAsString(persona);
writeValueAsString()
converteix un objectePersona
a una cadena XML. - Lectura d’arxius XML:
XmlMapper xmlMapper = new XmlMapper(); File xmlFile = new File("persona.xml"); Persona persona = xmlMapper.readValue(xmlFile, Persona.class);
readValue()
llegeix les dades d’un fitxer XML i les deserialitza en un objectePersona
. - Serialització d’objectes Java a un fitxer XML:
XmlMapper xmlMapper = new XmlMapper(); Persona persona = new Persona("John", 30); xmlMapper.writeValue(new File("persona.xml"), persona);
writeValue()
serialitza un objectePersona
i l’emmagatzema com un fitxer XML.
Anotacions de Jackson per a XML
Jackson ofereix diverses anotacions per personalitzar el mapeig entre objectes Java i XML, similar a les anotacions que es fan servir amb JSON. A continuació es detallen les anotacions més importants per treballar amb XML:
-
@JacksonXmlProperty
:
Anotació que s’utilitza per mapejar un camp d’una classe Java a un element XML específic. AmblocalName
, es defineix el nom de l’element en l’XML.import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; public class Persona { @JacksonXmlProperty(localName = "Nom") private String nom; @JacksonXmlProperty(localName = "Edat") private int edat; // Getters i Setters public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public int getEdat() { return edat; } public void setEdat(int edat) { this.edat = edat; } }
Resultat XML:
<Persona> <Nom>John</Nom> <Edat>30</Edat> </Persona>
L’atribut
nom
es mapeja a l’element XML<Nom>
, iedat
es mapeja a<Edat>
, seguint el nom específicat a l’anotació. -
@JacksonXmlElementWrapper
:S’utilitza per encapsular una llista d’elements dins d’un element de nivell superior, com ara
<alumnes>
que envolta diversos<alumne>
. Es a dir, permet crear un element que conté una col·lecció d’elements, (List, Set, Map, etc.).import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import java.util.List; public class Classe { @JacksonXmlElementWrapper(localName = "alumnes") @JacksonXmlProperty(localName = "alumne") private List<Alumne> alumnes; // Getters i Setters public List<Alumne> getAlumnes() { return alumnes; } public void setAlumnes(List<Alumne> alumnes) { this.alumnes = alumnes; } }
Resultat XML:
<Classe> <alumnes> <alumne> <nom>Anna</nom> <edat>22</edat> </alumne> <alumne> <nom>Marc</nom> <edat>23</edat> </alumne> </alumnes> </Classe>
A l’exemple, l’anotació
@JacksonXmlElementWrapper
crea l’element<alumnes>
que conté diversos elements<alumne>
. Cada alumne es representa amb les seves dades individuals. -
@JacksonXmlText
:
Mapeja el contingut de text d’un element XML directament a un camp de la classe. És útil quan l’element XML no té subelements, només un valor de text.import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText; public class Missatge { @JacksonXmlText private String text; // Constructor, Getter i Setter public Missatge(String text) { this.text = text; } public String getText() { return text; } public void setText(String text) { this.text = text; } }
Resultat XML:
<Missatge>Benvingut al sistema!</Missatge>
L’element
<Missatge>
conté directament el text “Benvingut al sistema!” gràcies a l’anotació@JacksonXmlText
. -
@JacksonXmlRootElement
:
Aquesta anotació defineix l’element arrel d’una classe Java quan es serialitza a XML.import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; @JacksonXmlRootElement(localName = "llibre") public class Llibre { private String titol; private String autor; // Constructor, Getters i Setters public Llibre(String titol, String autor) { this.titol = titol; this.autor = autor; } public String getTitol() { return titol; } public void setTitol(String titol) { this.titol = titol; } public String getAutor() { return autor; } public void setAutor(String autor) { this.autor = autor; } }
Resultat XML:
<llibre> <titol>El Nom del Vent</titol> <autor>Patrick Rothfuss</autor> </llibre>
En aquest cas, l’element arrel del document XML és
<llibre>
, gràcies a l’anotació@JacksonXmlRootElement
. -
@JacksonXmlProperty(isAttribute = true)
:
Aquesta anotació permet mapejar un camp com a un atribut d’un element XML.import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; public class Producte { @JacksonXmlProperty(isAttribute = true) private String id; @JacksonXmlProperty(localName = "nom") private String nom; // Constructor, Getters i Setters public Producte(String id, String nom) { this.id = id; this.nom = nom; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } }
Resultat XML:
<Producte id="123"> <nom>Ordinador</nom> </Producte>
Aquí,
id
és un atribut de l’element<Producte>
gràcies a@JacksonXmlProperty(isAttribute = true)
, mentre quenom
es manté com un subelement. -
@JacksonXmlCData
:
Aquesta anotació fa que el contingut d’un camp es mapege com un bloc CDATA dins de l’XML.import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData; public class Comentari { @JacksonXmlCData private String contingut; // Constructor, Getter i Setter public Comentari(String contingut) { this.contingut = contingut; } public String getContingut() { return contingut; } public void setContingut(String contingut) { this.contingut = contingut; } }
Resultat XML:
<Comentari><![CDATA[Això és un comentari amb <caràcters especials>!]]></Comentari>
L’anotació
@JacksonXmlCData
fa que el contingut del campcontingut
es representi com a CDATA, evitant problemes amb caràcters especials en el XML.
Resum anotacions XML
Anotació | Descripció |
---|---|
@JacksonXmlProperty | Mapeja un camp de la classe Java a un element XML amb un nom específic. Amb localName es pot definir el nom de l’element XML. També pot ser utilitzat per marcar un camp com a atribut si s’estableix isAttribute = true . |
@JacksonXmlElementWrapper | Envolta una col·lecció (com List , Set , Map ) amb un element XML superior. Amb localName , s’especifica el nom de l’element que contindrà la llista d’elements. |
@JacksonXmlText | Mapeja el contingut de text d’un element XML directament a un camp de la classe. S’utilitza quan l’element XML no té atributs ni subelements, només text. |
@JacksonXmlRootElement | Defineix l’element XML arrel per a la classe Java. localName especifica el nom de l’element arrel en l’XML. |
@JacksonXmlCData | Indica que el contingut del camp ha de ser emmagatzemat com un bloc CDATA en el document XML, permetent incloure caràcters especials sense errors de sintaxi. |
@JacksonXmlProperty(isAttribute = true) | Mapeja un camp com un atribut d’un element XML, en lloc de com un subelement, afegint-lo com a atribut dins de l’etiqueta XML. |
@JacksonXmlProperty(namespace = "url") | Assigna un espai de noms (namespace) a un element XML, útil quan es treballa amb XML que requereix espais de noms específics. |
Exemples Guiats
De XML a Java – Deserialitzant amb Jackson
Jackson facilita la conversió de dades XML a objectes Java mitjançant la classe XmlMapper
. Aquest procés es coneix com deserialització, i consisteix a transformar un document XML en objectes Java que representen les dades contingudes en l’XML.
Important - Dependències Maven:
Recorda que has d’afegir les dependències maven de Jackson XML al teu fitxer
pom.xml
per utilitzar aquesta funcionalitat. En este cas, necessitem afegir la següent dependència:
- jackson-databin : que importa les classes de Jackson per a la deserialització i serialització d’XML.
- jackson-dataformat-xml: afegeix a Jackson la capacitat de treballar amb XML.
Partim del següent document XML:
<persona>
<nom>Jaume Aragó</nom>
<edat>68</edat>
<adreces>
<adreca tipus="casa">
<carrer>Avinguda Datileres</carrer>
<ciutat>Benizahat</ciutat>
</adreca>
<adreca tipus="oficina">
<carrer>Canto del Bobet</carrer>
<ciutat>Benigaslo</ciutat>
</adreca>
</adreces>
<notes>
<![CDATA[Esta és una persona molt important.]]>
</notes>
</persona>
Creem els POJOs
Per crear les classes POJO (Plain Old Java Objects) a partir d’un document XML, cal tenir en compte:
- Identificar els elements i atributs del document XML que es mapegen com a camps a les classes Java.
- Cada element i atribut ha de tenir un camp corresponent a les nostres classes.
- Crear classes Java que representen les estructures del document, cada classe ha de correspondre a un element o grup d’elements relacionats del document XML.
public class Persona {
private String nom;
private int edat;
private List<Adreca> adreces;
private String notes;
// Constructors, getters i setters
}
public class Adreca {
private String tipus;
private String carrer;
private String ciutat;
// Constructors, getters i setters
}
Posem les Anotacions per al Mapejament XML
Per a indicar com fer el mapeig entre els elements XML i els camps de les classes Java, cal afegir anotacions de Jackson. Utilitzem les anotacions següents:
@JacksonXmlRootElement
: Indica l’element XML arrel que representa la classe Java.@JacksonXmlProperty
: Indica com s’ha de mapejar un camp a un element XML.@JacksonXmlElementWrapper
: S’utilitza per gestionar col·leccions dins d’elements agrupats.@JacksonXmlText
: Mapeja el contingut de text d’un element XML directament a un camp Java.
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
@JacksonXmlRootElement(localName = "persona")
public class Persona {
@JacksonXmlProperty(localName = "nom")
private String nom;
@JacksonXmlProperty(localName = "edat")
private int edat;
@JacksonXmlElementWrapper(localName = "adreces")
@JacksonXmlProperty(localName = "adreca")
private List<Adreca> adreces;
@JacksonXmlText(value = false)
private String notes;
// Constructors, getters i setters
}
public class Adreca {
@JacksonXmlProperty(isAttribute = true, localName = "tipus")
private String tipus;
@JacksonXmlProperty(localName = "carrer")
private String carrer;
@JacksonXmlProperty(localName = "ciutat")
private String ciutat;
// Constructors, getters i setters
}
Deserialització d’XML en un Objecte Java
Una volta tenim les classes POJO amb les anotacions adequades, podem utilitzar XmlMapper
per deserialitzar l’XML en un objecte Java.
L’objecte resultant pot accedir a les dades XML a través dels seus mètodes getters.
Creem la Classe Principal
• Creem una instància de la classe XmlMapper
de Jackson per treballar amb XML:
XmlMapper xmlMapper = new XmlMapper();
• Utilitzem XmlMapper
per llegir i deserialitzar el contingut del document XML en una instància de la classe Persona
:
Persona persona = xmlMapper.readValue(xml, Persona.class);
• Comprovem les dades deserialitzades mostrant-les per pantalla (amb els GETTER
s i, en l’exemple, amb un FOR..EACH
per a la col·lecció).
• Gestionem les possibles excepcions amb throws
o un try-catch
.
Deserialització des d’una Cadena XML
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Main {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
String xml = "<persona>... (com es mostra més amunt) ...</persona>";
Persona persona = xmlMapper.readValue(xml, Persona.class);
System.out.println("Nom: " + persona.getNom());
System.out.println("Edat: " + persona.getEdat());
System.out.println("Notes: " + persona.getNotes());
for (Adreca adreca : persona.getAdreces()) {
System.out.println("Tipus d'adreça: " + adreca.getTipus());
System.out.println("Carrer: " + adreca.getCarrer());
System.out.println("Ciutat: " + adreca.getCiutat());
System.out.println();
}
}
}
**Sortida esperada *
Nom: Jaume Aragó
Edat: 68
Notes: Esta és una persona molt important.
Tipus d'adreça: casa
Carrer: Avinguda Datileres
Ciutat: Benizahat
Tipus d'adreça: oficina
Carrer: Canto del Bobet
Ciutat: Benigaslo
Deserialització des d’un Fitxer XML
També es pot deserialitzar l’XML a partir d’un fitxer utilitzant la classe File
. Aquí tens el codi reescrit i formatat:
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.File;
public class Main {
public static void main(String[] args) {
XmlMapper xmlMapper = new XmlMapper();
File xmlFile = new File("persona.xml");
try {
if (xmlFile.exists()) {
// Deserialitzar el fitxer XML a un objecte Persona
Persona persona = xmlMapper.readValue(xmlFile, Persona.class);
// Mostrar les dades deserialitzades per pantalla
System.out.println("Nom: " + persona.getNom());
System.out.println("Edat: " + persona.getEdat());
System.out.println("Notes: " + persona.getNotes());
// Iterar sobre les adreces i mostrar-ne la informació
for (Adreca adreca : persona.getAdreces()) {
System.out.println("Tipus d'adreça: " + adreca.getTipus());
System.out.println("Carrer: " + adreca.getCarrer());
System.out.println("Ciutat: " + adreca.getCiutat());
System.out.println();
}
} else {
System.err.println("El fitxer XML no existeix.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Descripció del Codi:
- Importacions: Importa la classe
XmlMapper
per treballar amb XML i la classeFile
per gestionar fitxers. - Creació de l’Objecte
XmlMapper
: Facilita la deserialització del fitxer XML en un objecte Java. - Creació del fitxer XML: Es defineix un objecte
File
que apunta a “persona.xml”. - Verificació de l’Existència del Fitxer: Es comprova si el fitxer existeix abans de processar-lo.
- Deserialització: Si el fitxer existeix, es converteix el contingut XML a un objecte de la classe
Persona
. - Visualització de les dades: Es mostren les propietats de l’objecte
Persona
i les seves adreces per pantalla. - Gestió d’Excepcions: Si es produeix una excepció durant la deserialització o el processament del fitxer, aquesta es captura i mostra amb
e.printStackTrace()
.
El codi llegeix un fitxer XML, el converteix en un objecte Java de la classe Persona
, i en mostra les dades per pantalla, incloent la informació de les seves adreces. Si el fitxer no existeix, es mostra un missatge d’error.
Sortida esperada (si el fitxer persona.xml
conté el mateix contingut que l’exemple XML anterior):
Nom: Jaume Aragó
Edat: 68
Notes: Esta és una persona molt important.
Tipus d'adreça: casa
Carrer: Avinguda Datileres
Ciutat: Benizahat
Tipus d'adreça: oficina
Carrer: Canto del Bobet
Ciutat: Benigaslo
De Java a XML – Serialitzant amb Jackson
La serialització converteix un objecte Java en un document XML. Jackson facilita aquest procés amb la classe XmlMapper
.
Dependències Maven:
Hem d’incorporar les mateixes dependències maven per a Jackson que als exemples anteriors. Per tant, afegim al
pom.xml
:
- jackson-databin : que importa les classes de Jackson per a la deserialització i serialització d’XML.
- jackson-dataformat-xml: afegeix a Jackson la capacitat de treballar amb XML.
Creem les Classes POJO
Per a la serialització, utilitzem les mateixes classes Persona
i Adreca
que hem definit anteriorment.
public class Persona {
private String nom;
private int edat;
private List<Adreca> adreces;
private String notes;
// Constructors, getters i setters
}
public class Adreca {
private String tipus;
private String carrer;
private String ciutat;
// Constructors, getters i setters
}
Posem les anotacions per al mapejament XML
Igual que en la deserialització, per indicar com realitzar el mapeig entre els elements XML i els camps de les classes Java, hem d’utilitzar anotacions de Jackson. @JacksonXmlRootElement, @JacksonXmlProperty, @JacksonXmlElementWrapper, @JacksonXmlText
, entre d’altres.
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
import java.util.List;
@JacksonXmlRootElement(localName = "persona")
public class Persona {
@JacksonXmlProperty(localName = "nom")
private String nom;
@JacksonXmlProperty(localName = "edat")
private int edat;
@JacksonXmlElementWrapper(localName = "adreces")
@JacksonXmlProperty(localName = "adreca")
private List<Adreca> adreces;
@JacksonXmlText
private String notes;
// Constructors
public Persona() {}
public Persona(String nom, int edat, List<Adreca> adreces, String notes) {
this.nom = nom;
this.edat = edat;
this.adreces = adreces;
this.notes = notes;
}
// Getters i Setters
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public int getEdat() {
return edat;
}
public void setEdat(int edat) {
this.edat = edat;
}
public List<Adreca> getAdreces() {
return adreces;
}
public void setAdreces(List<Adreca> adreces) {
this.adreces = adreces;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
}
public class Adreca {
@JacksonXmlProperty(localName = "tipus")
private String tipus;
@JacksonXmlProperty(localName = "carrer")
private String carrer;
@JacksonXmlProperty(localName = "ciutat")
private String ciutat;
// Constructors
public Adreca() {}
public Adreca(String tipus, String carrer, String ciutat) {
this.tipus = tipus;
this.carrer = carrer;
this.ciutat = ciutat;
}
// Getters i Setters
public String getTipus() {
return tipus;
}
public void setTipus(String tipus) {
this.tipus = tipus;
}
public String getCarrer() {
return carrer;
}
public void setCarrer(String carrer) {
this.carrer = carrer;
}
public String getCiutat() {
return ciutat;
}
public void setCiutat(String ciutat) {
this.ciutat = ciutat;
}
}
Creem la Classe Principal
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.util.ArrayList;
import java.util.List;
public class Principal {
public static void main(String[] args) {
// Inicialitza l'XmlMapper
XmlMapper xmlMapper = new XmlMapper();
// Crear una instància de Persona
Persona persona = new Persona();
persona.setNom("Jaume Aragó");
persona.setEdat(68);
persona.setNotes("Esta és una persona molt important.");
List<Adreca> adreces = new ArrayList<>();
Adreca casa = new Adreca();
casa.setTipus("casa");
casa.setCarrer("Avinguda Datileres");
casa.setCiutat("Benizahat");
adreces.add(casa);
Adreca oficina = new Adreca();
oficina.setTipus("oficina");
oficina.setCarrer("Canto del Bobet");
oficina.setCiutat("Benigaslo");
adreces.add(oficina);
persona.setAdreces(adreces);
try {
// Serialitzar Persona a XML
String xml = xmlMapper.writeValueAsString(persona);
System.out.println(xml);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Sortida esperada:
<persona>
<nom>Jaume Aragó</nom>
<edat>68</edat>
<adreces>
<adreca tipus="casa">
<carrer>Avinguda Datileres</carrer>
<ciutat>Benizahat</ciutat>
</adreca>
<adreca tipus="oficina">
<carrer>Canto del Bobet</carrer>
<ciutat>Benigaslo</ciutat>
</adreca>
</adreces>
<notes>Esta és una persona molt important.</notes>
</persona>
Usant un fitxer, la classe File i un Filewriter
Aquí tens el codi estructurat i formatejat:
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.File;
import java.io.FileWriter;
public class Principal {
public static void main(String[] args) {
// Inicialitza l'XmlMapper
XmlMapper xmlMapper = new XmlMapper();
// Crear una instància de Persona
Persona persona = new Persona();
persona.setNom("Jaume Aragó");
persona.setEdat(68);
// Configurar altres camps de Persona i Adreca si és necessari
try {
// Serialitzar Persona com a XML
String xml = xmlMapper.writeValueAsString(persona);
// Especificar la ruta del fitxer on voleu guardar l'XML
String rutaFitxer = "persona.xml";
// Crear un fitxer i escriure-hi l'XML
File fitxer = new File(rutaFitxer);
FileWriter fileWriter = new FileWriter(fitxer);
fileWriter.write(xml);
fileWriter.close();
System.out.println("L'XML s'ha guardat correctament a " + rutaFitxer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Descripció del codi:
- Crear la instància de
XmlMapper
: És la classe que facilita la conversió d’objectes Java a XML. - Crear una instància de
Persona
: Assigna valors als camps de l’objectePersona
(nom i edat). - Serialitzar a XML: Utilitza el mètode
writeValueAsString()
deXmlMapper
per convertir l’objectePersona
a una cadena XML. - Especificar la ruta del fitxer: Indica el nom del fitxer (
persona.xml
) on es guardarà el contingut XML. - Escriure l’XML al fitxer: Utilitza
FileWriter
per escriure la cadena XML al fitxer i després tanca elFileWriter
. - Gestió d’excepcions: Amb un bloc
try-catch
, es gestiona qualsevol excepció que pugui ocórrer durant la serialització o escriptura del fitxer.
Exemple Complet:
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
public class Principal {
public static void main(String[] args) {
try {
// Crea una nova instància de Persona amb les dades especificades
Persona persona = new Persona();
persona.setNom("Jaume Aragó");
persona.setEdat(68);
Adreca adrecaCasa = new Adreca();
adrecaCasa.setTipus("casa");
adrecaCasa.setCarrer("Avinguda Datileres");
adrecaCasa.setCiutat("Benizahat");
Adreca adrecaOficina = new Adreca();
adrecaOficina.setTipus("oficina");
adrecaOficina.setCarrer("Canto del Bobet");
adrecaOficina.setCiutat("Benigaslo");
List<Adreca> adreces = new ArrayList<>();
adreces.add(adrecaCasa);
adreces.add(adrecaOficina);
persona.setAdreces(adreces);
String notes = "Aquesta és una persona molt important.";
persona.setNotes(notes);
// Inicialitza l'XmlMapper
XmlMapper xmlMapper = new XmlMapper();
// Afig la declaració (capçalera de l'XML)
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
// Habilita la identació de l'XML
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
// Serialitza l'objecte Persona com a XML
String xml = xmlMapper.writeValueAsString(persona);
// Guarda l'XML com a fitxer "persona.xml"
FileWriter fileWriter = new FileWriter("persona.xml");
fileWriter.write(xml);
fileWriter.close();
System.out.println("L'XML s'ha creat i guardat com a fitxer persona.xml.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Notícies sobre el Codi
-
Configuració de la Capçalera XML:
La línia:
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
Configura
xmlMapper
per incloure una declaració XML (XML Declaration) a la sortida quan es serialitza un objecte a XML. La declaració XML és una línia opcional al principi d’un document XML que especifica la versió de XML i la codificació de caràcters utilitzada en el document. En aquest cas, es genera una línia com aquesta:<?xml version="1.0" encoding="UTF-8"?>
-
Identació de l’XML:
La línia:
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
Fa que l'XML generat siga **indentat**, és a dir, afegeix espais i salts de línia per a fer-lo més llegible. Per exemple, un XML amb identació es veuria així: ```xml <?xml version="1.0" encoding="UTF-8"?> <persona> <nom>Jaume Aragó</nom> <edat>68</edat> <!-- altres elements i atributs --> </persona>
Nota sobre l’ús de CDATA en notes
Si volem que <notes>
aparega com a CDATA en la classe Persona
, hem de modificar el camp notes
de la següent manera:
@JacksonXmlCData
private String notes;
En lloc de:
@JacksonXmlText(value = false)
private String notes;
Aquesta modificació fa que el contingut de notes
es guarde en l’XML dins d’una secció CDATA, així:
<notes><![CDATA[Aquesta és una persona molt important.]]></notes>
Eixida Esperada del Codi:
Si es configura correctament la classe Persona
i el codi es compila i s’executa, es generaria un fitxer persona.xml
amb un contingut similar al següent:
<?xml version="1.0" encoding="UTF-8"?>
<persona>
<nom>Jaume Aragó</nom>
<edat>68</edat>
<adreces>
<adreca tipus="casa">
<carrer>Avinguda Datileres</carrer>
<ciutat>Benizahat</ciutat>
</adreca>
<adreca tipus="oficina">
<carrer>Canto del Bobet</carrer>
<ciutat>Benigaslo</ciutat>
</adreca>
</adreces>
<notes><![CDATA[Aquesta és una persona molt important.]]></notes>
</persona>
El codi crea una instància de la classe Persona
, la configura amb dades específiques, i la serialitza a un fitxer XML amb el contingut esmentat, incloent-hi la capçalera XML i la secció CDATA si es configura el camp notes
com a tal.