Leer y escribir XML en Java

¿Qué es XML?

La abreviatura "XML" significa - e X tensible M arkup Language. Tiene una estructura de marcado similar a HTML y fue diseñada para almacenar y transportar datos. Define un conjunto de reglas que lo hacen legible tanto para humanos como para máquinas.
A pesar de ser un lenguaje de marcado como HTML, XML se usa comúnmente para intercambiar datos entre servicios web, backends y front-end, al igual que JSON y se considera su antecesor.
Si está interesado en leer acerca de leer y escribir JSON en Java , ¡ya lo hemos cubierto!
Es importante tener en cuenta que XML no tiene un conjunto predefinido de etiquetas como HTML, sino que está definido por el usuario. Es esta flexibilidad la que llevó a la creación de múltiples formatos de documentos como RSS , Atom , SOAP y XHTML . Todos estos formatos son subconjuntos de XML, en esencia.
Veamos un documento XML simple, que replica el mismo objeto que usamos anteriormente con respecto a JSON:
<?xml version="1.0" encoding="UTF-8"?>  
<person>  
    <age>31</age>
    <hobbies>
        <element>Football</element>
        <element>Swimming</element>
    </hobbies>
    <isMarried>true</isMarried>
    <kids>
        <person>
            <age>5</age>
            <name>Billy</name>
        </person>
        <person>
            <age>3</age>
            <name>Milly</name>
        </person>
    </kids>
    <name>Benjamin Watson</name>
</person>  
La diferencia clave entre XML y JSON es que estamos definiendo este archivo con la versión XML y la codificación al principio del documento con una <?xml>etiqueta. Otra diferencia es que cada propiedad de objeto debe estar envuelta en su propia etiqueta - <age>31</age>Los elementos de la matriz no se pueden especificar sin una etiqueta, por lo tanto, para enumerarlos, los estamos envolviendo <element>...</element>dentro de la <hobbies>...</hobbies>etiqueta.

JAXB

Como XML es un formato basado en texto, puede usar las mismas técnicas para leerlo y escribirlo como cualquier otro archivo de texto.
Java, sin embargo, proporciona una forma conveniente de manipular XML utilizando el marco denominado J ava A rchitecture para X ML B inding, o JAXB para abreviar. Nos permite asignar objetos Java a documentos XML y viceversa. JAXB se introdujo por primera vez en JDK 1.6 y no está disponible en versiones anteriores.
Dado que JAXB es un marco JDK estándar, no es necesario incluir dependencias externas al proyecto para JDK 1.6+.
Nota: si está utilizando Java 9 o superior, debe incluir un parámetro adicional al javaccomando. Si está utilizando un IDE como IntelliJ IDEA o Eclipse, busque una configuración de opciones de compilador adicional y asegúrese de que incluya la --add-modules java.xml.bindcadena.
En el caso de IntelliJ IDEA, se encuentra en el menú Preferences-> Build, Execution, Deployment-> Compiler-> Java Compiler.
Si aún obtendrías errores, Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBContextincluso después de agregar la opción de compilador adicional, agrega las siguientes dependencias de Maven:
<dependency>  
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.11</version>
</dependency>  
<dependency>  
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.11</version>
</dependency>  
<dependency>  
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.11</version>
</dependency>  
<dependency>  
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>  
Los conceptos básicos de JAXB se denominan Marshalling y Unmarshaling . Están, como era de esperar, representados por las clases MarshallerUnmarshaller.
Marshalling es el proceso de conversión de objetos Java en XML, y Unmarshalling es el proceso de conversión de XML en objetos Java.
JAXB se configura mediante anotaciones que se importan del javax.xml.bind.annotationspaquete.
Definamos una clase de Java que represente a la persona descrita en nuestro documento XML:
@XmlRootElement
public class Person {

    public Person(String name, int age, boolean isMarried, List<String> hobbies, List<Person> kids) {
        this.name = name;
        this.age = age;
        this.isMarried = isMarried;
        this.hobbies = hobbies;
        this.kids = kids;
    }

    public Person(String name, int age) {
        this(name, age, false, null, null);
    }

    private String name;
    private Integer age;
    private Boolean isMarried;
    private List<String> hobbies;
    private List<Person> kids;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMarried() {
        return isMarried;
    }

    @XmlElement(name = "isMarried")
    public void setMarried(boolean married) {
        isMarried = married;
    }

    @XmlElementWrapper(name = "hobbies")
    @XmlElement(name = "element")
    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public List<Person> getKids() {
        return kids;
    }

    @XmlElementWrapper(name = "kids")
    @XmlElement(name = "person")
    public void setKids(List<Person> kids) {
        this.kids = kids;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", isMarried=" + isMarried +
                ", hobbies=" + hobbies +
                ", kids=" + kids +
                '}';
    }
}
@XmlRootElement- asigna una clase o un tipo de enumeración a un elemento XML. Describe el elemento raíz del documento XML y debe especificarse en la Persondeclaración de clase.
@XmlElementWrapper- genera un elemento de envoltura alrededor de la representación XML, un Listen nuestro caso. Los elementos de la lista deben especificarse explícitamente mediante la @XMLElementanotación.
@XMLElement- asigna una propiedad de un objeto Java a un elemento XML derivado del nombre de la propiedad. Para especificar un nombre de propiedad XML diferente, lo estamos incluyendo como un parámetro de cadena a la declaración de anotación, es decir (name = "person").

Implacable

El ejemplo más simple de la técnica de clasificación nos requerirá crear una JAXBContextinstancia, pasando a Person.classcomo el único parámetro de entrada de su constructor.
A continuación, se crea el impalador llamando a un createUnmarshaller()método, y una instancia del real Personse genera por su unmarshal()método.
Asegúrese de usar tipecast explícito, ya que el unmarshalmétodo devuelve el tipo Object:
public class Solution {  
    public static void main(String[] args) throws Exception {
        Person person = XMLtoPersonExample("person.xml");
        System.out.println(person);
    }

    private static Person XMLtoPersonExample(String filename) throws Exception {
        File file = new File(filename);
        JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        return (Person) jaxbUnmarshaller.unmarshal(file);
    }
}
Después de ejecutar este código, deberías ver algo como:
Person{name='Benjamin Watson', age=31, isMarried=true, hobbies=[Football, Swimming], kids=[Person{name='Billy', age=5, isMarried=null, hobbies=null, kids=null}, Person{name='Milly', age=3, isMarried=null, hobbies=null, kids=null}]}  

Marshalling

Para demostrar la capacidad de JAXB para escribir un archivo XML utilizando el objeto Java como fuente, agregaremos el siguiente método:
private static void personToXMLExample(String filename, Person person) throws Exception {  
    File file = new File(filename);
    JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);

    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.marshal(person, file);
    jaxbMarshaller.marshal(person, System.out);
}
Es muy similar al ejemplo anterior e incluye la creación de un JAXBContextnuevo. Esta vez, sin embargo, el proceso irá en la dirección inversa, y la salida XML se escribirá en el archivo y la consola.
Añadiendo una invocación de este método como la última cadena en el Solution.main()similar:
personToXMLExample("person-output.xml", person);  
Y ejecutándolo, obtendremos una desafortunada excepción.
Exception in thread "main" java.lang.NullPointerException  
    at com.stackabuse.xml.Person.isMarried(Person.java:49)
    at com.stackabuse.xml.Person$JaxbAccessorM_isMarried_setMarried_boolean.get(MethodAccessor_Boolean.java:61)
...
Hemos cometido un error al establecer el isMarriedtipo de campo en la clase de envoltorio Booleany el tipo de retorno del captador isMarried()en primitivo boolean, lo que lleva a JAXB a intentar desempaquetar nully lanzar una NullPointerExceptioncomo resultado de ello.
Una solución rápida y fácil para esto sería alinear esos dos con uno booleandos Boolean.
Después de solucionar el problema, obtendremos la siguiente salida tanto para la consola como para el archivo:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
<person>  
    <age>31</age>
    <hobbies>
        <element>Football</element>
        <element>Swimming</element>
    </hobbies>
    <kids>
        <person>
            <age>5</age>
            <name>Billy</name>
        </person>
        <person>
            <age>3</age>
            <name>Milly</name>
        </person>
    </kids>
    <isMarried>true</isMarried>
    <name>Benjamin Watson</name>
</person>  
Como vemos, es totalmente idéntico al archivo XML original que hemos incluido en el personobjeto.

Conclusión

La lectura y escritura de XML en Java podría lograrse fácilmente mediante el uso del marco JAXB. Usando anotaciones, definimos las reglas de mapeo entre clases Java y documentos XML que representan sus objetos.
XML a menudo se considera un formato obsoleto que es inferior a JSON. Sin embargo, saber cómo leerlo y escribirlo usando Java, es una habilidad útil para cualquier desarrollador de software, ya que muchos de los servicios en la web todavía lo están usando y aún no tienen una API JSON. Este es también el caso de muchos formatos de archivo que almacenan datos en archivos con formato XML.
Aunque, en caso de que JSON sea lo tuyo, sugeriría leer sobre leer y escribir JSON en Java, ¡también lo tenemos cubierto!

Acerca de: Programator

Somos Instinto Programador

0 comentarios:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Con tecnología de Blogger.