XmlBeans es una librería de Apache que logra manipular de forma más amigable los XML pudiéndolos mapear a objetos y tipos de datos en java, de tal manera que podamos navegar en la estructura de un fichero XML con datos, desde objetos Java. Esto nos permite aprovechar todo el potencial de XML.
La librería en resumen maneja los siguientes 3 casos de uso:
- Mapear de un xsd o varios a clases java que quedan empaquetadas en un .jar (desde terminal de comandos).
- Usar el .jar generado (en el punto 1) en nuestro proyecto para poder manipular el contenido de un XML con Datos (desde código Java).
- Navegar dentro de un XML sobre el cual desconocemos completamente la estructura, por medio de un cursor (desde código Java).
Definición del formato XSD y comparativa con DTD
Un DTD (Definición de Tipo de Documento) es un tipo de documento para especificar el formato de un XML, no admite tipos de datos y proporciona un control no muy preciso sobre el formato de un XML. DTD no permite especificar el formato del contenido del XML.
Un XSD (Definición de esquema XML), es un tipo de documento más actual que sirve para determinar la validez de un documento XML, por medio de este definimos su estructura; es decir que elementos, tipos de datos, atributos, en que orden y cuantas veces se pueden repetir. XSD si nos permite especificar el formato del contenido.
Comparativa
DTD | XSD |
Proporciona menos control sobre la estructura XML. | XSD proporciona mayor control sobre la estructura |
No admite tipos de datos | Admite tipos de datos |
Es más difícil de comprender que XSD | Es más fácil de comprender que DTD |
Para poder transmitir información entre sistemas se suele especificar el formato de XML a usar con un XSD, entonces una organización nos puede especificar el formato de XML que esperan recibir.
Mapeo de XSD a .JAR
Para poder mapear un conjunto de XSDs a objetos y empaquetarlos en un .JAR será necesario ejecutar el comando scomp de la librería XMLBeans (en un cmd).
La sintaxis es la siguiente:
scomp -out %jarName% -compiler "%JavaCompiler%" *.xsd
Donde jarName es el nombre del .JAR de salida, JavaCompiler es la ruta al javac en nuestro jdk, y *.xsd indica que se agregaran al .JAR todos los xsd encontrados en el directorio donde estamos posicionados.
Una vez ejecutamos el comando si todo está en orden nos generará el .JAR, el cual debemos importar a nuestro proyecto, ya sea de forma manual o agregando la dependencia local a nuestro Maven.
Si usamos Maven y queremos agregar este repositorio como local debemos realizar el siguiente procedimiento:
mvn install:install-file -Dfile=C:\Users\nico\Desktop\beans.jar
-DgroupId=com.ejemplo -DartifactId=beans -Dversion=4.27
-Dpackaging=jar -DgeneratePom=true
Esa línea lo que hace es agregar el jar con los parámetros ingresados (a nuestro directorio .m2) para que después podamos agregarlo al pom de la siguiente forma:
<dependency>
<groupId>com.ejemplo</groupId>
<artifactId>beans</artifactId>
<version>4.27</version>
</dependency>
Una vez hecho esto nosotros podremos importar a nuestras clases los objetos que contiene dicho jar. Si queremos saber cual es la estructura del import a agregar, podemos explorar el .jar generado con 7-zip.
Manipular el contenido de un XML usando los objetos mapeados en el .JAR
Una vez que nosotros importamos las clases del .JAR generado, si usamos el siguiente snippet podremos manipular cualquiera de estos objetos, también debemos disponer de un XML que se ajuste al formato del XSD inicial.
String xmlFile = "rutaAlXML";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
CharsetEncoder encoder1252 = Charset.forName("Windows-1252").newEncoder();
System.out.println(encoder1252.getClass().getCanonicalName());
BufferedReader br = new BufferedReader(new FileReader(xmlFile));
StringWriter sw = new StringWriter();
while (br.ready()) {
sw.write(br.readLine()+"\n");
}
encoder1252.onUnmappableCharacter(CodingErrorAction.REPLACE);
System.out.println(encoder1252.replacement()[0]);
ByteBuffer bb1252= encoder1252.encode(CharBuffer.wrap(sw.getBuffer()));
String s1252 = new String(bb1252.array(),Charset.forName("Windows-1252"));
PersonaDocument persona = PersonaDocument.Factory.parse(s1252);
System.out.println("Persona >> Datos >> FechaNacimiento = "+ persona.getPersona().getDatos().getFechaNacimiento());
En la línea final se observa cómo se accede a un dato, navegando en toda la estructura de datos del xml con getters, y se hace un println del mismo.
Estos objetos generados por XMLBeans pueden tomarse como DTOs porque son totalmente carentes de lógica, solo contienen la definición del tipo de dato y facilitan el acceso a la información del XML.
Introducción a cursores
Para poder navegar dentro de un XML desconociendo su esquema, xmlBeans propone el manejo del concepto de cursores. Un cursor representa un lugar específico dentro del documento XML, el cual puede desplazarse usando el modelo de tokens (existen 9 tipos de token), pudiendo también obtener y establecer valores dentro del documento.
La gran desventaja de los cursores es que; al desconocer completamente el esquema, el grado de complejidad al intentar manipular un XML aumenta mucho.
Lo más recomendable puede ser tener un esquema de XSDs bien definidos para mapearlos a objetos y poder trabajar así más fácilmente desde java.
Para finalizar les dejo este enlace para obtener la librería XmlBeans de Apache