SlideShare una empresa de Scribd logo
1 de 32
Descargar para leer sin conexión
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
TEMARIO DE CURSO
PROGRAMACIÓN JAVA SE
CAPÍTULO 15
PERSISTENCIA.
FICHEROS XML, JSON, PDF
© Iñaki Martín
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional.
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (I)
Crear un fichero XML usando DOM
2
๏ DOM (Document Object Model) es un estándar de la WWW, que define cómo representar documentos HTML, XHTML
y XML. En base, define qué tipo de etiquetas y atributos puede haber, en qué orden y con que estructura
๏ Java posee clases para trabajar con ficheros XML o HTML tratándolos como objetos DOM. La mecánica es leer el
fichero HTML o XML y almacenarlo en un objeto Document, y procesar este, o escribir un objeto Document en un
fichero XML/HTML
๏ Para el procesamiento de ficheros DOM se usan, entre otras, las clases Node, Element, y NodeList.
๏ Antes de seguir es importante que se entienda la diferencia entre dichas clases:
‣ Un Node es cualquier objeto que haya en un documento DOM.
‣ Un Element es un tipo específico de Node, al igual que hay otros muchos tipos de nodos (textos de nodo,
comentarios, el propio Document entero es un tipo -Document-)
‣ Un documento DOM consiste en una jerarquía de nodos en modo árbol, en el que cada nodo tiene hermanos, un
padre, o hijos. Un NodeList es un conjunto de nodos, que pueden definirse a través de “hijos de X”, “todos los de
nombre X” , etc (todo ello con métodos que veremos más adelante)
๏ La página siguiente contiene un resumen de las clases y métodos básicos para trabajar con DOM
Ejemplo DOM: estructura DOM de un fichero HTML:
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (III) 3
Métodos de uso en DOM (para crear XML)
CLASE DEVUELVE METODOS DESCRIPCION
Document Node getDocumentElement()
Devuelve el nodo raiz de un documento
nivel1 = miDocDom.createElement("personal");
Document Node createElement("texto")
Crea un nodo cuyo nombre es el texto del parametro
nivel11 = miDocDom.createElement("empleado");
Node void setAttribute("texto", "contenido")
Crea, en el Element aplicado, un atributo de nombre "texto" con valor "contenido"
((Element) unnodo).setAttribute("codigoEmp", "2323");
Document Node createTextNode("texto")
Crea un nodo de texto (el valor de una etiqueta)
nodotexto = miDocDom.createTextNode("Pedro");
Node void appendChild( otronodo )
Añade otroNodo como un nodo hijo del nodo llamante
unnodo.appendChild(sunodohijo);
Métodos de uso en DOM (para leer XML)
CLASE DEVUELVE METODOS DESCRIPCION
Document Node getDocumentElement()
Devuelve el nodo raiz de un documento
nivel1 = miDocDom.createElement("personal");
Node NodeList getElementsByTagName("texto")
Devuelve una lista con los nodos que tienen por nombre "texto"
NodeList listaDeNodosDeEmpleados = nodoRaiz.getElementsByTagName("empleado");
NodeList int getLength()
Devuelve el tamaño de una NodeList
int m listaNodosHijosDeEmpleado.getLength();
Node NodeList getChildNodes()
Devuelve una lista con los nodos hijos del nodo al que se aplica el metodo
NodeList listaNodosHijos = nodoEmpleado.getChildNodes();
NodeList Node item( num )
Devuelve el nodo num-esimo de la lista de nodos a la que se aplica el metodo
Node dato = listaNodos.item(m);
Node String getNodeName()
Devuelve el nombre del nodo al que se aplica el metodo
if (dato.getNodeName().equals("nombre"))
Node Node getFirstChild()
Devuelve el primer hijo del nodo al que se aplica el metodo
Node datoContenido = dato.getFirstChild();
Node String getNodeValue()
Devuelve el valor (el contenido) del nodo al que se aplica el metodo
String atrib= nodo.getAttributes().getNamedItem("cod").getNodeValue()
Node
NamedNo
deMap
getAttributes()
Devuelve todos los atributos de nodo al que se aplica el metodo
NamedNodeMap mapanodo = nodoEmpleado.getAttributes()
NamedNod
eMap Node getNamedItem( texto )
Devuelve el elemento llamado "texto" de los que existen en la colección
Node unnodo = nodoEmpleado.getAttributes().getNamedItem("codDptoPertenecia")
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (IV) 4
public class Empleado {
String codigoEmpleado;
String nombreEmpleado;
String apellidoEmpleado;
String codDptoPertenecia;
public Empleado() { }
public Empleado(String codigoEmpleado, String nombreEmpleado,
String apellidoEmpleado, String codDptoPertenecia) {
this.codigoEmpleado = codigoEmpleado;
this.nombreEmpleado = nombreEmpleado;
this.apellidoEmpleado = apellidoEmpleado;
this.codDptoPertenecia = codDptoPertenecia;
}
public String getCodigoEmpleado() { return codigoEmpleado; }
public String getNombreEmpleado() { return nombreEmpleado; }
public String getApellidoEmpleado() {return apellidoEmpleado; }
public String getCodDptoPertenecia() { return codDptoPertenecia; }
public void setCodigoEmpleado(String codigoEmpleado) {
this.codigoEmpleado = codigoEmpleado;
}
public void setNombreEmpleado(String nombreEmpleado) {
this.nombreEmpleado = nombreEmpleado;
}
public void setApellidoEmpleado(String apellidoEmpleado) {
this.apellidoEmpleado = apellidoEmpleado;
}
public void setCodDptoPertenecia(String codDptoPertenecia) {
this.codDptoPertenecia = codDptoPertenecia;
}
}
๏ Como siempre, se ve todo mucho mejor en un ejemplo práctico : vamos a guardar, en un ficheroXML, una lista de objetos de las
clase Empleado
๏ Empleado es una clase POJO normal (POJO es una clase que solo tiene atributos, constructor completo, getters y setters
๏ Es obligatorio que tenga un constructor vacío:
Fichero XML objetivo del ejemplo
<datosDePersonal> // raiz
<personal>
<empleado codigoEmp="c10" codDeptoPertenencia="d10">
<nombre>Pepe</nombre>
<apellido>Perez</apellido>
</empleado>
<empleado codigoEmp="c11" codDeptoPertenencia="d20">
<nombre>Eva</nombre>
<apellido>Lopez</apellido>
</empleado>
</personal>
</datosDePersonal>
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
Desde el main de nuestro proyecto se invocan a dichos métodos
Ficheros XML con DOM (IV) 5
public class EjercicioDOM {
ArrayList<Empleado> listaEmpleados;
public static void main(String[] args) {
Document miDocumentoDom;
GestionDOM gd = new GestionDOM();
listaEmpleados = new ArrayList<>();
listaEmpleados.add(new Empleado(“c10","Pepe", "Perez", “d10"));
listaEmpleados.add(new Empleado("c11","Eva", "Lopez", “d20”));
// Creamos un documento DOM llamado miDocumentoDom con el arraylist leido
miDocumentoDom = gd.crearDocumentoDOMcondatosJava(listaEmpleados);
// creamos un fichero DOM1.xml con el documento miDocumentoDom
gd.guardarDocumentoDOMcomoXML( miDocumentoDom, "DOM1.xml" );
// Creamos un documento DOM parseando un fichero XML existemte
miDocumentoDom = gd.leerFicheroXmlEnDocumentDOM("DOM1.xml");
// Creamos nuevamente el arraylist con el DOM parseado de DOM1.xml
listaEmpleados = gd.crearClasesJavaDesdeDocumentDOM(miDocumentoDom);
}
}
1
2
3
4
๏ Para este ejercicio proponemos una solución modularizada, con cuatro métodos que hagan las siguientes cosas :
dos son para crear un fichero XML, y otros dos para leer un fichero XML ya existente):
• crearDocumentoDOMcondatosJava() : desde objetos Java, se crea un objeto Document, que tiene ya la estructura XML
• guardarDocumentoDOMcomoXML() : el objeto Document ya creado, se escribe en un fichero de disco
• leerFicheroXmlEnDocumentDOM() : lee un fichero de disco con contenido XML y lo almacena en un objeto Document
• crearClasesJavaDesdeDocumentDOM() : desde un objeto Document, se crean nuevamente las clases Java originales
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (V)
public class GestionDOM {
Node nodo_personal, nodo_empleado, nodo_raiz,nodo_nombre, nodo_apellidos, nodo_nombre_texto, nodo_apellidos_texto;
public Document crearDocumentoDOMcondatosJava(ArrayList<Empleado> listaEmp) {
Document miDocDom; //Objeto Document que almacena el DOM del XML seleccionado.
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
DOMImplementation implementation = builder.getDOMImplementation();
String nombreDelNodoRaiz = "datosDePersonal";
miDocDom = implementation.createDocument(null, nombreDelNodoRaiz, null);
miDocDom.setXmlVersion("1.0");
//-- Crear los nodos de todas las etiquetas generales
nodo_raiz = miDocDom.getDocumentElement();
nodo_personal = miDocDom.createElement("personal");
// recorrer el arraylist de empleados
for (Empleado em : listaEmp) {
//-- Crear los nodos de todas las etiquetas del empleado
nodo_empleado = miDocDom.createElement("empleado");
nodo_nombre = miDocDom.createElement("nombre");
nodo_apellidos = miDocDom.createElement("apellidos");
//-- Crear los nodos de texto con los valores de cada empleado
nodo_nombre_texto = miDocDom.createTextNode(em.getNombreEmpleado());
nodo_apellidos_texto = miDocDom.createTextNode(em.getApellidoEmpleado());
//-- Añade atributos como elementos de texto, esto no crea nodos, modifica los ya creados
((Element) nodo_empleado).setAttribute("codigoEmp", em.getCodigoEmpleado());
((Element) nodo_empleado).setAttribute("codDptoPertenencia", em.getCodDptoPertenecia() + "");
//-- Añadir cada nodo a su padre
nodo_nombre.appendChild(nodo_nombre_texto);
nodo_apellidos.appendChild(nodo_apellidos_texto);
nodo_empleado.appendChild(nodo_nombre);
nodo_empleado.appendChild(nodo_apellidos);
nodo_personal.appendChild(nodo_empleado);
}
// Se añade el nodo personal a nodo raiz, no se hace dentro del for, pues hay que meter todos los empleados
// en la etiqueta personal....
nodo_raiz.appendChild(nodo_personal);
// se devuelve finalmente el document creado
return miDocDom;
} catch (Exception e) {
return null;
}
}
6
1
<datosDePersonal> // raiz
<personal>
<empleado codigoEmp="c10" codDeptoPertenencia="d10">
<nombre>Pepe</nombre>
<apellido>Perez</apellido>
</empleado>
<empleado codigoEmp="c11" codDeptoPertenencia="d20">
<nombre>Eva</nombre>
<apellido>Lopez</apellido>
</empleado>
</personal>
</datosDePersonal>
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (VI)
public void guardarDocumentoDOMcomoXML(Document pdoc, String nombreFicheroXML) {
try {
//guardar el documento DOM como un fichero ;
//Crea un fichero llamado salida.xml
File archivo_xml = new File(nombreFicheroXML);
//Especifica el formato de salida
OutputFormat format = new OutputFormat(pdoc);
//Especifica que la salida esté indentada.
format.setIndenting(true);
//Escribe el contenido en el FILE
XMLSerializer serializer = new XMLSerializer(new FileOutputStream(archivo_xml), format);
serializer.serialize(pdoc);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
7
2
public Document leerFicheroXmlEnDocumentDOM(String fichero) {
Document document = null;
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
document = builder.parse(new FileInputStream(fichero));
} catch (Exception e1) {
e1.printStackTrace();
}
return document;
}
3
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (VII)
public ArrayList<Empleado> crearClasesJavaDesdeDocumentDOM(Document document) {
String nombreDelNodoRaiz, nombre, apellidos, cod, dep;
ArrayList<Empleado> alistaEmpleados = new ArrayList<>();
nodo_raiz = document.getDocumentElement(); // sacar del document el nodo raiz
nombreDelNodoRaiz = nodo_raiz.getNodeName(); // sacar el nombre del nodo raiz
// cogemos los hijos directos de raiz
NodeList listaHijosRaiz = ((Element)nodo_raiz).getElementsByTagName("personal");
// como solo debe tener un hijo, este es personal
nodo_personal = listaHijosRaiz.item(0);
Element elemento_personal = (Element) nodo_personal;
// cogemos los hijos directos de personal
NodeList listaEmpleados = elemento_personal.getElementsByTagName("empleado");
for (int t = 0; t < listaEmpleados.getLength(); t++) {
nodo_empleado = listaEmpleados.item(t);
nombre = getValorNodoHijoSimple("nombre", nodo_empleado);
apellidos = getValorNodoHijoSimple("apellidos", nodo_empleado);
cod = getValorAtributo("codigoEmp", nodo_empleado);
dep = getValorAtributo("codDptoPertenencia", nodo_empleado);
Empleado emp = new Empleado(cod, nombre, apellidos, Integer.parseInt(dep));
alistaEmpleados.add(emp);
}
return alistaEmpleados;
}
8
4
Tambien puede ser util, tras extraer el nodo raiz,
usar el método normalize(), que elimina los nodos
vacíos del XML y otros problemas de estructura:
nodo_raiz.normalize();
(continua) ➡
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (VIII)
public String getValorNodoHijoSimple(String etiquetaABuscar, Element elementoPadre) {
String resultado = "";
// sacar una lista de todos los nodo-etiqueta que se llame "etiquetaABuscar" y sea hijo de "elementoPadre"
// con el ejemplo, esto da una lista de elementos <nombre>
NodeList listaNodosHijos = elementoPadre.getElementsByTagName(etiquetaABuscar);
// sacar el unico nodo-etiqueta que tiene esa lista (se sabe que el nodo es simple)
// con el ejemplo, esto da el unico elemento <nombre> que existe
Node nodo = listaNodosHijos.item(0);
// sacar del nodo-etiqueta su único hijo, que es el CONTENIDO de la etiqueta (que sigue siendo un nodo...)
// en el ejemplo, es Pepe, pero con formato de nodo
if (nodo != null) {
Node contenido = nodo.getFirstChild();
// sacar del nodo-contenido su valor
// en el ejemplo, ahora si, la cadena "Pepe"
resultado = contenido.getNodeValue();
}
return resultado;
}
// Version sobrecargada, con Node en vez de Element
public String getValorNodoHijoSimple(String etiquetaABuscar, Node nodoPadre) {
Element elementoPadre = (Element) nodoPadre;
return getValorNodoHijoSimple(etiquetaABuscar, elementoPadre);
}
public String getValorAtributo(String atributoABuscar, Node nodoPadre) {
String resultado = "";
NamedNodeMap nnm = nodoPadre.getAttributes();
Node attr = nnm.getNamedItem(atributoABuscar);
if (attr != null) {
resultado = attr.getNodeValue();
}
return resultado;
}
9
4 (continuación )
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
๏ Para la gestión de estos eventos, es necesario crear una clase propia heredera de DefaultHandler (un Handler es, en
jerga informática, un tipo de objetos que “manejan” o “manipulan” información)
Esta clase dispone de varios métodos, de los que hemos de sobrescribir, como poco, los siguientes:
- startDocument(): se “dispara” al comenzar a leer el documento xml.
- endDocument(): se “dispara” al finalizar de leer el documento xml.
- startElement(): se “dispara” al leer una etiqueta de comienzo de elemento
Aquí se deben leer los atributos de las etiquetas.
Cuando el analizador encuentra una etiqueta de inicio llama a startElement, indicando el nombre de la etiqueta. Pero
cuidado que no indica la etiqueta padre, así que no es fácil saber dónde esta la etiqueta encontrada. La mejor
solución es tener una/s variables que indiquen por dónde va pasando el analizador.
- endElement(): se “dispara” al leer una etiqueta de fin de elemento.
- characters(): se “dispara” al encontrar una cadena de texto (cuidado, pues puede haber cadenas ocultas).
Cuando el analizador encuentra un texto dentro de una etiqueta, llama al método characters. Como no se sabe qué
texto se esta leyendo (pues no se indica la etiqueta donde se encuentra el texto) es útil lo dicho antes, que se haya
guardado previamente al pasar por el startElement qué etiqueta se esta procesando
El método characters recibe tres parametros: (char[] chars, int start, int length)
• chars indica la cadena global que esta procesando el analizador,
• Start donde comienza el texto que esta leyendo ahora y
• Length que tamaño tiene el texto.
Por lo tanto, lo que se hace es crear un String pasándole esos mismos tres parámetros (si, existe un constructor de
String con esos datos) y así recogemos el texto de la etiqueta
10
๏ Otro mecanismo para leer XML desde Java es usando SAX (Simple API for XML). SAX fue el primer “parseador” de XML
adoptado como API para XML en Java, y tiene ventajas e inconvenientes frente a DOM u otros mecanismos, que veremos más
adelante (un “parseador”, parser en ingles, es un programa que “traduce” algo siguiendo unas de análisis sintáctico).
๏ SAX es un parser con acceso en serie (va recorriendo el xml poco a poco) y basado en eventos (va llamando a eventos
según encuentra determinadas partes del xml, como el principio de etiqueta, fin de etiqueta, texto, ….)
Leer Xml con SAX desde Java
SAX en Java (I)
1
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 11
public class Alumno {
private String nombre, apellidos;
private String id;
private double nota;
public Alumno() {
}
public Alumno(String nombre, String id, double nota) {
this.nombre = nombre;
this.id = id;
this.nota = nota;
}
public String getApellidos() {
return apellidos;
}
public void setApellidos(String apellidos) {
this.apellidos = apellidos;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getNota() {
return nota;
}
public void setNota(double nota) {
this.nota = nota;
}
public String toString() {
return “{“+"nombre="+nombre+","+apellido+": id=“+
id +":"+"nota="+nota+"}";
}
}
SAX en Java (II)
<clase>
<alumno id = "33">
<nombre>Ana</nombre>
<apellido>Arranz</apellido>
<nota>8</nota>
</alumno>
<alumno id = "17">
<nombre>Pepe</nombre>
<apellido>Perez</apellido>
<nota>5</nota>
</alumno>
</clase>
๏ Clase Alumno, que será la que se
use para crear un arrayList tras leer
lo que contiene el xml
๏ Fichero XML que deseamos leer
๏ El ejemplo siguiente explica mejor como leer un xml y otros métodos que se usan en el proceso:
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 12
public class MiHandlerSax extends DefaultHandler { // CREA EL HANDLER QUE SE USA LUEGO PARA PARSEAR EL XML
ArrayList<Alumno> listaAlumnos = new ArrayList<>();
Alumno unalumno;
String etiquetaActual = "";
@Override
public void startDocument() throws SAXException { // esto se ejecuta al comenzar a leer el documento. }
@Override
public void endDocument() throws SAXException { // esto se ejecuta al finalizar de leer el documento }
@Override
public void startElement(String uri, String localName, String qname, Attributes attributes) throws SAXException {
// debemos guardarnos qué etiqueta estamos leyendo en cada momento
etiquetaActual = qname;
// al emplezar a leer cada elemento, solo me interesan los elementos que tienen atributos
if (qname.equalsIgnoreCase("alumno")) {
unalumno = new Alumno(); // como es comienzo de alumno, creo un nuevo alumno para darle datos
String elId = attributes.getValue(“id"); // la etiqueta tiene atributo, asi que lo leo
if (elId != null) unalumno.setId(elId); // nos aseguramos que el atributo tiene valor
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// aqui entra en cuanto empieza a leerse un texo dentro de una etiqueta,
// sabemos que etiqueta estamos leyendo, asi que cogemos el texto...
String texto = new String(ch, start, length);
// y lo asignamos al atributo del alumno que corresponde...
if (etiquetaActual.equalsIgnoreCase("nombre")) {
unalumno.setNombre(texto);
}
if (etiquetaActual.equalsIgnoreCase("id")) {
unalumno.setId(texto);
}
if (etiquetaActual.equalsIgnoreCase("apellido")) {
unalumno.setApellido(texto);
}
if (etiquetaActual.equalsIgnoreCase("nota")) {
unalumno.setNota(Double.parseDouble(texto));
listaAlumnos.add(unalumno); // como la nota es la ultima etiqueta de un alumno, añadimos el alumno ya creado al arraylist
}
etiquetaActual = "";
}
@Override
public void endElement(String uri, String localName, String name){ // aqui entra en cuanto se leer una etiqueta de fin }
public ArrayList<Alumno> getListaAlumnos() {
return listaAlumnos;
}
}
SAX en Java (III)
//-- Tambien se pueden leer todos los atributos
//—- y ver su nombre y valor
for(int i=0;i<attributes.getLength();i++){
System.out.println("atributo: "+attributes.getQName(i));
System.out.println("valor: "+attributes.getValue(i));
}
1
๏ Crear la clase propia que herede de DefaultHandler y que permita leer uno a uno todo el contenido del XML
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 13
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
public class PruebaSAX {
public static void main(String[] args) {
try {
MiHandlerSax miHandler = miHandler = new MiHandlerSax();
// Creamos un analizador de XML con una fábrica de analizadores
XMLReader xmlreader = XMLReaderFactory.createXMLReader();
// Añadimos nuestro handler al analizador
xmlreader.setContentHandler(miHandler);
// Analizamos con el analizador el xml deseado
xmlreader.parse(new InputSource(new FileInputStream("alumnosxml.xml")));
// Probamos que el analizador ha leido el arraylist correctamente
ArrayList<Alumno> listaalumnos = miHandler.getListaAlumnos();
for (Alumno a : listaalumnos) {
System.out.println(a);
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
consola
{nombre=Ana: id=33:nota=8.0}
{nombre=Pepe: id=17:nota=5.0}
SAX en Java (IV)
๏ Una vez creado nuestro handler, usar la clase XMLReaderFactory para obtener un objeto de tipo XMLReader (un analizador)
๏ A ese analizador se le agrega como propiedad nuestro handler con el método setter setContentHandler()
๏ Finalmente se ejecuta el análisis con el método parse() pasándole el fichero XML a analizar
2
Cuidado: no podemos asumir alegremente que todo el texto de un elemento se lea con una sola llamada al método characters. Puede
ocurrir, dependiendo de ciertas circunstancias, que el analizador llame dos o más veces al método para leer un texto, haciendo lecturas
parciales en cada llamada. No es un comportamiento habitual, pero si así ocurre, la solución es ir acumulando el texto de distintas
llamadas, y usar el método endElement para asegurar que se han acabado todas las llamadas a characters
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 14SAX en Java (V)
Escribir Xml con SAX desde Java
๏ Para escribir un fichero XML con herramientas SAX, se usan los siguientes pasos:
1. Crear un objeto de la clase XMLStreamWriter, que escribe textos con formato XML en un buffer, intermedio, ubicado en otro
objeto, esta vez de la clase StringWriter
2. Crear el documento y añadir una etiqueta de cabecera xml, como por ejemplo <?xml version="1.0" ?>
3. Con writeStartElement() se crea una etiqueta de apertura, con el nombre que se le indica.
4. Con writeAttribute() añade un atributo a la última etiqueta que se haya abierto
5. Con writeCharacters() añade un contenido de texto a la última etiqueta que se haya abierto
6. Con writeEndElement() se añade una etiqueta de cierre, asociada a la última etiqueta que se haya abierto. Por ello no es
necesario incluir un valor
7. Para anidar etiquetas, crear un writeStartElement() sin haber cerrado el anterior
8. Siempre añadir un writeEndDocument() para cerrar el documento se que se esta escribiendo
// StringWriter crea objetos que procesan un buffer para construir cadenas
StringWriter stringWriter = new StringWriter();
// XMLOutputFactory crea una fabrica de procesar archivos XML
XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();
// XMLStringWriter crea objetos capaces de almacenar etiquetas XML con estructura
XMLStreamWriter xMLStreamWriter = xMLOutputFactory.createXMLStreamWriter(stringWriter);
xMLStreamWriter.writeStartDocument();
xMLStreamWriter.writeStartElement("alumno");
xMLStreamWriter.writeStartElement("nombre");
xMLStreamWriter.writeCharacters(a.getNombre());
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeStartElement("apellido");
xMLStreamWriter.writeCharacters(a.getApellidos());
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeStartElement(“nombre");
xMLStreamWriter.writeAttribute("nacionalidad", “Española");
xMLStreamWriter.writeCharacters(a.getNombre());
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndDocument();
Etiqueta“alumno”
Etiqueta
“nombre”
Etiqueta
“apellido”
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
writeStartElement() crea una etiqueta de
apertura, con el nombre que se le indica
Así, writeStartElement(“clase") crea la etiqueta
<clase>
Toda etiqueta de apertura ha de tener después
su correspondiente etiqueta de cierre
15
public static void crearXmlConSax(ArrayList<Alumno> listaalumnos) {
try {
// StringWriter crea objetos que procesan un buffer para construir cadenas
StringWriter stringWriter = new StringWriter();
// XMLOutputFactory crea una fabrica de procesar archivos XML
XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();
// XMLStringWriter crea objetos capaces de almacenar etiquetas XML con estructura
XMLStreamWriter xMLStreamWriter = xMLOutputFactory.createXMLStreamWriter(stringWriter);
xMLStreamWriter.writeStartDocument();
xMLStreamWriter.writeStartElement("clase");
for (Alumno a : listaalumnos) { // Recorremos el arraylist para crear cada alumno
xMLStreamWriter.writeStartElement("alumno");
xMLStreamWriter.writeAttribute("id", a.getId());
xMLStreamWriter.writeStartElement("nombre");
xMLStreamWriter.writeCharacters(a.getNombre());
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeStartElement("apellido");
xMLStreamWriter.writeCharacters(a.getApellidos());
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeStartElement("nota");
xMLStreamWriter.writeCharacters(a.getNota() + "");
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndElement();
}
xMLStreamWriter.writeEndDocument();
xMLStreamWriter.flush();
xMLStreamWriter.close();
// convertir el objeto stringWriter creado en un String
String xmlString = stringWriter.getBuffer().toString();
stringWriter.close();
// escribir el String en un fichero xml fisico
PrintWriter pw = new PrintWriter("alumnosDesdeSax.xml");
pw.print(xmlString);
pw.close();
}
catch (XMLStreamException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
}
SAX en Java (VI)
Un writeStartElement() tras otro
writeStartElement(), sin haber cerrado el
anterior, anida la segunda etiqueta dentro de la
anterior
Un writeAttribute() añade un atributo a la última
etiqueta que se haya abierto
Un writeCharacters() añade un contenido de
texto a la última etiqueta que se haya abierto
Un writeEndElement() crea una etiqueta de
cierre, asociada a la última etiqueta que se haya
abierto. Por ello no es necesario incluir un valor
Así se construye un String con el contenido del
documento xml creado en el buffer
Un writeEndDocument() cierra el documento
XML que estamos creando
writeStartDocument() inicia el documento,
creando una etiqueta de cabecera xml, como
<?xml version="1.0" ?>
Así escribimos en un fichero XML físico el
contenido del String recién construido
๏ Ejemplo que escribe en un
XML un array de Alumno
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 16JAXB en Java (I)
๏ Otro mecanismo para leer XML desde Java es usando JAXB. Está ya implementado en java desde la versión 6, con lo que no
es necesario añadir ninguna biblioteca
๏ JAXB utiliza anotaciones para marcar, en una clase, qué información se va a convertir en etiquetas, qué en texto y qué en
atributos
๏ Se basa en dos acciones, llamadas marshal y unmarshal, de la clase Marshaller (traducido, algo así como organizador):
‣ Marshalling – Convertir un objeto Java en un fichero XML .
‣ Unmarshalling – Convertir un fichero XML en un objeto Java
๏ El mecanismo es el siguiente:
- Se crea un Contexto, que es un objeto de la clase JAXBContext. El contexto se crea con el método newInstance()
indicándole a dicho contexto con qué clase va a tener que trabajar
- Con dicho contexto, se crea un Marshaller, con el método createMarshaller()
- Con el objeto marshaller ya se usan los métodos marshal() y unmurshal() para crear o leer de un fichero xml
Crear Xml y leer con JAXB desde Java
fichero.xml
Clase javacontexto
marshaller
genera (marshal)
lee
crea
Regenera (unmarshal)
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 17JAXB en Java (II)
๏ Se crea un xml con una clase POJO simple @XmlRootElement
@XmlType(propOrder={“nota","nombre"})
public class Alumno {
private String nombre;
private String id;
private double nota;
public Alumno() { }
public Alumno(String nombre, String id, double nota) {
this.nombre = nombre;
this.id = id;
this.nota = nota;
}
public String getNombre() { return nombre; }
public String getId() { return id; }
public double getNota() { return nota; }
@XmlElement
public void setNombre(String nombre) {
this.nombre = nombre;
}
@XmlAttribute
public void setId(String id) {
this.id = id;
}
@XmlElement(name=“nota”)
public void setNota(double nota) {
this.nota = nota;
}
@Override
public String toString() {
return nombre+":"+" id="+id +":"+"nota="+nota+"}";
}
}
Clase Alumno, que será la
que se use para crear un
xml y luego leer de él.
@XmlRootElement identifica a la clase que va
a constituir el nodo raiz del XML
Se puede indicar que en el xml tenga otro
nombre, con el formato
@XmlRootElement(name=“Estudiante")
@XmlElement identifica a cada etiqueta interna
dentro del nodo Alumno. No es obligatorio (ver
más adelante “reglas de uso de anotaciones
JAXB)
@XmlAttribute identifica que el elemento será
un atributo del nodo alumno
Los getters son necesarios si existe un setter
correspondiente que se ha marcado como
elemento o atributo (ver más adelante “reglas de
uso de anotaciones JAXB)
@XmlType usa varios valores, con propOrder
se indica el orden de los elementos dentro de
nodo. Es opcional, si no se usa, se crean en el
orden de la aparición en la clase
Ejemplo primero, con una clase con atributos simples ( 1ª parte )
1
(name=“nota”) identifica el nombre que se dará
finalmente a cada etiqueta en el XML. Es
opcional, si no se usa, se procesa el XML con el
nombre del atributo
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 18
public class JAXBPrueba {
public static void main(String[] args) {
Alumno a1 = new Alumno("Pepe", "E221", 5.1);
try {
// Crear el contexto, vale tanto para marshal como para unmarshal
JAXBContext jaxbContext = JAXBContext.newInstance(Alumno.class);
// -------------- CREAR FICHERO XML --------------------
// ------------------------------------------------------
// Crear marshaller
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// asi el xml tiene formato indentado y mas elegante
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
File file = new File("JAXBejemplo1.xml");
jaxbMarshaller.marshal(a1, file); //asi, lo que crea el marshaller va a fichero
jaxbMarshaller.marshal(a1, System.out); //asi, lo que crea el marshaller va a pantalla
// -------------- LEER FICHERO XML ---------------------
// ------------------------------------------------------
// Crear unmarshaller
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
// la solucion del unmarshall es un object, se necesita casting para convertirlo en alumno
Alumno al2 = (Alumno) jaxbUnmarshaller.unmarshal(file);
System.out.println(“…………………………“);
System.out.println("Alumno leido: "+al2);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
consola
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<alumno id="E221">
<nota>5.1</nota>
<nombre>Pepe</nombre>
</alumno>
................................
Alumno leido: {nombre=Pepe: id=E221:nota=5.1}
JAXB en Java (III)
Ejemplo primero, con una clase con atributos simples ( y 2ª )
2
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 19
@XmlRootElement(name = "Automovil")
@XmlType(propOrder = {"marca", "modelo", "propietario"})
public class Coche {
private String marca;
private String modelo;
private int precio;
private Persona propietario;
public Coche() {
}
@XmlElement
public void setPropietario(Persona propietario) {
this.propietario = propietario;
}
@XmlElement
public void setMarca(String marca) {
this.marca = marca;
}
@XmlElement
public void setModelo(String modelo) {
this.modelo = modelo;
}
@XmlAttribute
public void setPrecio(int precio) {
this.precio = precio;
}
public Persona getPropietario() {
return propietario;
}
public String getMarca() {
return marca;
}
public int getPrecio() {
return precio;
}
public String getModelo() {
return modelo;
}
}
JAXB en Java (IV)
Ejemplo segundo, con un atributo que es un objeto
Coche x2 = new Coche();
x2.setMarca("Kia");
x2.setModelo("Niro");
x2.setPrecio(19000);
x2.setPropietario(new Persona("Eva", "55322242K"));
JAXBContext contexto = JAXBContext.newInstance(Coche.class);
// -------------- CREAR FICHERO XML --------------------
Marshaller miMarshaller = contexto.createMarshaller();
miMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
miMarshaller.marshal(x2, new File("JAXBejemplo2.xml"));
miMarshaller.marshal(x2, System.out);
// -------------- LEER FICHERO XML ——————————
Unmarshaller miUnmarshaller = contexto.createUnmarshaller();
Coche nuevocoche = (Coche) miUnmarshaller.unmarshal( new File("JAXBejemplo2.xml"));
System.out.println("................................");
System.out.println("Coche leido: " + nuevocoche.getMarca());
System.out.println("Propietario: " + nuevocoche.getPropietario().getNombre());
public class Persona {
String nombre;
String dni;
public Persona() {
}
public Persona(String nombre, String dni) {
this.nombre = nombre;
this.dni = dni;
}
public String getNombre() { return nombre; }
public String getDni() { return dni; }
public void setNombre(String nombre) {this.nombre = nombre;}
public void setDni(String dni) { this.dni = dni; }
}
๏ En este caso la clase que se procesa tiene un atributo
que es el objeto de otra clase
๏ Advertir que las anotaciones se hacen obligatorias solo
en la clase principal.
consola
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Automovil precio="19000">
<marca>Kia</marca>
<modelo>Niro</modelo>
<propietario>
<dni>55322242K</dni>
<nombre>Eva</nombre>
</propietario>
</Automovil>
................................
Coche leido: Kia
Propietario: Eva
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 20JAXB en Java (V)
Ejemplo tercero, con un atributo que es una colección ( 1ª parte )
@XmlRootElement(name="GarageLopez")
public class Garage implements Serializable {
String nombre;
List<Coche> listacoches ;
List<String> condiciones ;
public Garage() {
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public List<String> getCondiciones() {
return condiciones;
}
public List<Coche> getListacoches() {
return listacoches;
}
@XmlElementWrapper(name=“Condiciones generales”)
@XmlElement(name = "Condiciones")
public void setCondiciones(List<String> condiciones) {
this.condiciones = condiciones;
}
@XmlElementWrapper(name="CochesOcupados")
@XmlElement(name = "Coches")
public void setListacoches(List<Coche> listacoches) {
this.listacoches = listacoches;
}
}
public class Coche {
private String marca;
private String modelo;
private int precio;
private Persona propietario;
public Coche() {
}
public void setPropietario(Persona propietario) { this.propietario = propietario; }
public void setMarca(String marca) { this.marca = marca; }
public void setModelo(String modelo) { this.modelo = modelo; }
public void setPrecio(int precio) { this.precio = precio;c }
public Persona getPropietario() { return propietario; }
public String getMarca() { return marca; }
public String getModelo() { return modelo; }
@XmlAttribute
public int getPrecio() { return precio; }
}
public class Persona {
String nombre;
String dni;
public Persona() {
}
public Persona(String nombre, String dni) {
this.nombre = nombre;
this.dni = dni;
}
public String getNombre() { return nombre; }
public String getDni() { return dni; }
public void setNombre(String nombre) {this.nombre = nombre;}
public void setDni(String dni) { this.dni = dni; }
}
๏ En este caso la clase que se procesa tiene dos
atributos que son listas de objetos de otra clase
๏ Advertir que las anotaciones se hacen obligatorias solo en la
clase principal, aunque se ha añadido solo una, para hacer
que precio sea atributo de la etiqueta Coche
@XmlElementWrapper indica que los las etiquetas
del elemento que se procesa (normalmente una
coleccion) se agrupan bajo una etiqueta global, suyo
nombre es el que se añade
1
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 21JAXB en Java (VI)
Ejemplo tercero, con un atributo que es una colección ( y 2ª )
Coche x = new Coche();
x.setMarca("Seat");
x.setModelo("Ibiza");
x2.setPrecio(7000);
x.setPropietario(new Persona("Paco", “66444373L"));
Coche x2 = new Coche();
x2.setMarca("Kia");
x2.setModelo("Niro");
x2.setPrecio(19000);
x2.setPropietario(new Persona("Eva", "55322242K"));
ArrayList<Coche> coches = new ArrayList<>();
coches.add(x);
coches.add(x2);
ArrayList<String> condiciones = new ArrayList<>();
condiciones.add("salida emergencia");
condiciones.add("acceso con mando");
condiciones.add("area de lavado”);
Garage garage = new Garage();
garage.setNombre("SuperGarage");
garage.setListacoches(coches);
garage.setCondiciones(condiciones);
JAXBContext contexto = JAXBContext.newInstance(Garage.class);
Marshaller miMarshaller = contexto.createMarshaller();
miMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
miMarshaller.marshal(garage, new File("JAXBejemplo3.xml"));
miMarshaller.marshal(garage, System.out);
Unmarshaller miUnmarshaller = contexto.createUnmarshaller();
Garage nuevoGarage = (Garage) miUnmarshaller.unmarshal(new File(“JAXBejemplo3.xml"));
System.out.println("................................");
System.out.println("Garage: " + nuevoGarage.getNombre());
System.out.println("Coche 1 : " + nuevoGarage.getListacoches().get(1).getMarca());
System.out.println("Propietario 1: " + nuevoGarage.getListacoches().get(1).getPropietario().getNombre());
consola
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GarageLopez>
<CondicionesGenerales>
<Condiciones>salida emergencia</Condiciones>
<Condiciones>acceso con mando</Condiciones>
<Condiciones>area de lavado</Condiciones>
</CondicionesGenerales>
<CochesOcupados>
<Coches precio="9000">
<marca>Seat</marca>
<modelo>Ibiza</modelo>
<propietario>
<dni>66444373L</dni>
<nombre>Paco</nombre>
</propietario>
</Coches>
<Coches precio="19000">
<marca>Kia</marca>
<modelo>Niro</modelo>
<propietario>
<dni>55322242K</dni>
<nombre>Eva</nombre>
</propietario>
</Coches>
</CochesOcupados>
<nombre>SuperGarage</nombre>
</GarageLopez>
................................
Garage: SuperGarage
Coche 1 : Kia
Propietario 1: Eva
2
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 22JAXB en Java (VII)
REGLAS DE USO DE LAS ANOTACIONES JAXB
๏ @XMLElement :
1. No es necesario en absoluto su uso (salvo que se desee añadir a la etiqueta XML un nombre distinto al del propio
miembro de la clase). JAXB va a procesar por defecto y escribir en el XML:
‣ Cualquier atributo público (en tal caso, no deben tener @XMLElement sus getter ni setter, si existen estos métodos)
‣ Cualquier atributo privado, siempre que tenga su par de métodos públicos getter o setter. Además, deben existir los dos
métodos para el atributo privado.
2. Si se usa (por ejemplo para añadir a la etiqueta XML un nombre distinto al del propio atributo de la clase):
‣ Se puede usar indistintamente en los getters o setters, pero no en los dos a la vez
‣ Se puede usar directamente en el atributo, pero este no puede tener sin getters ni setters (el atributo puede ser public o
private, da igual)
‣ No se puede usar en un método que no sea getter o setter
‣ Si no se usan anotaciones,
3. Puede usarse simplemente la anotación @XMLElement o añadirle un valor para indicar el nombre que ha de tomar la
etiqueta en el XML : @XMLElement(name=“nombrexml”)
๏ @XMLElementWrapper :
4. No es obligatorio su uso con colecciones . Si no se usa, la colección se creará elemento a elemento en el XML. Si se
usa, entonces, todos los elementos de la colección tendrán un padre común, precisamente el indicado por el atributo-
colección donde se aplica @XMLElementWrapper , salvo que se indique expresamente un nuevo nombre con
@XMLElementWrapper(name=“nombreagrupadorxml”)
๏ @XmlAccessorType(XmlAccessType.NONE) :
5. Obliga al uso de anotaciones, no permitiendo que se generen por defecto según de indica la regal 1 indicada
anteriormente. El valor contrario (el que se aplica por defecto si no se pone nada) es
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 23JAXB en Java (VIII)
JAXB y clases de java.timeTemas avanzados
๏ JAXB no funciona correctamente si se usan clases que se han incorporado a la suite de JAVA con posterioridad a la implantación de
JAXB. Uno de los ejemplos es con el paquete java.time, clases con las que JAXB no tiene solución para serializar y deserializar
(convertir a bytes y recuperar de bytes) clases como LocalDate, LocalTime, LocalDateTime, y ZonedDateTime. Vamos, que con
esas clases, JAXB no funciona directamente.
๏ Para solucionarlo hay que crearse adaptadores personalizados que procesen el marshall y unmarshall de dichos datos. Este es un
ejemplo de un adaptador muy sencillo, pero que nos saca del apuro:
public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {
public LocalDate unmarshal(String v) throws Exception {
return LocalDate.parse(v);
}
public String marshal(LocalDate v) throws Exception {
return v.toString();
}
}
@XmlJavaTypeAdapter(value = LocalDateAdapter.class)
public LocalDate getFecha() {
return fecha;
}
๏ Posteriormente, no se pueden usar anotaciones directas como las ya vistas de JAXB en los atributos que sean LocalDate o
similares, sino hemos de usar la anotación genérica @XmlJavaTypeAdapter indicando que se aplica nuestro adaptador recién
creado, como en este ejemplo;
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 24
๏ Para crear contenido JSON vamos a usar una librería llamada GSON (https://github.com/google/gson)
๏ Descargar de dicha página el .jar con la librería a usar, crear un proyecto e instalar la librería en el mismo, bien por
medio de las preferencias del proyecto, o si se usa por ejemplo Gradle (como lo hace Android Studio) se añade la
dependencia directamente, sin tener que descargar ni instalar nada:
๏ Este es un simple ejemplo del uso de GSON, dentro de una clase, que crea el texto de un JSON desde un objeto, y
desde el propio texto, lo vuelve a montar en un objeto propio:
Crear texto JSON de un objeto Java
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}
class Libro {
String autor;
String titulo;
double precio;
public String convertirAJson() {
Gson unGson = new Gson();
String cadenaEnFormatoGSON = unGson.toJson(this);
return cadenaEnFormatoGSON;
}
public Libro recuperarDeJson(String cadenaEnFormatoGSON) {
Gson unGson = new Gson();
Libro libroRecuperado = unGson.fromJson(cadenaEnFormatoGSON, Libro.class);
return libroRecuperado;
}
public Libro(String autor, String titulo, double precio) {
this.autor = autor;
this.titulo = titulo;
this.precio = precio;
}
}
Si se desea una estructura mas
compleja, como un array o un
ArrayList, basta con meter el array
o ArrayList como atributo de la
clase, crear el objeto del mismo
modo, y recuperarlo también
igualmente (ejemplo en paginas
siguientes)
public class PruebaJSON {
public static void main(String[] args) {
Libro unlibro = new Libro("Cervantes", "EL Quijote", 33.50);
String objetoEnJSon = unlibro.convertirAJson();
System.out.println(objetoEnJSon);
Libro libroRecogidoDeJson = new Libro().recuperarDeJson(objetoEnJSon);
System.out.println(libroRecogidoDeJson.autor);
}
}
consola
{"autor":"Cervantes","titulo":"EL Quijote","precio":33.5}
Cervantes
JSON en Java (I)
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF 25
๏ En este caso, la clase contiene un array, pero la creación del JSON y
recuperación del mismo se hace… exactamente igual que antes
Crear texto JSON de una clase que contiene una colección (arrays o listas)
class Libreria {
String nombre;
Libro[] libros;
public Libreria(String nombre, Libro[] libros) {
this.nombre=nombre;
this.libros=libros;
}
public String convertirAJson() {
Gson unGson = new Gson();
String cadenaEnFormatoGSON = unGson.toJson(this);
return cadenaEnFormatoGSON;
}
public Libreria recuperarDeJson(String cadenaEnFormatoGSON) {
Gson unGson = new Gson();
Libreria libreriaRecuperada = unGson.fromJson(cadenaEnFormatoGSON, Libreria.class);
return libreriaRecuperada;
}
}
public class PruebaJSON {
public static void main(String[] args) {
Libro[] libros = new Libro[3];
libros[0] = new Libro("Cervantes", "El Quijote", 33.50);
libros[1] = new Libro("C. Jose Cela", "La Colmena", 11.80);
libros[2] = new Libro("C. Jose Cela", "San Camilo 1936", 22.00);
Libreria libreria = new Libreria("ViejosLibros", libros);
String libreriaEnJson = libreria.convertirAJson();
System.out.println(libreriaEnJson);
Libreria libreriaNueva = libreria.recuperarDeJson(libreriaEnJson);
System.out.println(libreriaNueva.nombre);
System.out.println(libreriaNueva.libros[1].titulo);
}
}
consola
{
"nombre": "ViejosLibros",
"libros": [{
"autor": "Cervantes",
"titulo": "El Quijote",
"precio": 33.5
}, {
"autor": "C. Jose Cela",
"titulo": "La Colmena",
"precio": 11.8
}, {
"autor": "C. Jose Cela",
"titulo": "San Camilo 1936",
"precio": 22.0
}]
}
ViejosLibros
La Colmena
JSON en Java (II)
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF JSON en Java (III) 26
๏ Aunque también se puede convertir a JSON una colección (array o arraylist)
directamente, sin que la colección forme parte de una clase.
a) Con un array, igual que con una clase, indicando al fromJSON que el tipo de
dato que se deserializa es un Libro[].class
Crear texto JSON directamente de una colección (arrays o listas)
Libro[] libros = new Libro[3];
libros[0] = new Libro("Cervantes", "El Quijote", 33.50);
libros[1] = new Libro("C. Jose Cela", "La Colmena", 11.80);
libros[2] = new Libro("C. Jose Cela", "San Camilo 1936", 22.00);
Gson unGson = new Gson();
String arrayEnFormatoGSON = unGson.toJson(libros);
System.out.println(arrayEnFormatoGSON);
Libro[] arrayRecuperado = unGson.fromJson(arrayEnFormatoGSON, Libro[].class);
System.out.println(libros[1].titulo);
ArrayList<Libro> libros = new ArrayList<Libro>();
libros.add( new Libro("Cervantes", "El Quijote", 33.50));
libros.add( new Libro("C. Jose Cela", "La Colmena", 11.80));
libros.add( new Libro("C. Jose Cela", "San Camilo 1936", 22.00));
Gson unGson = new Gson();
String arrayListEnFormatoGSON = unGson.toJson(libros);
System.out.println(arrayListEnFormatoGSON);
// No se puede usar en fromJSON un ArrayList como tipo de dato
// Hay que sacar el "tipo de dato" del ArrayList con la clase TypeToken de GSON
// y la clase Type de Java
Type typeDeArrayListDeLibro = new TypeToken<ArrayList<Libro>>(){}.getType();
ArrayList<Libro> arrayListRecuperado = unGson.fromJson(arrayListEnFormatoGSON, typeDeArrayListDeLibro);
System.out.println(arrayListRecuperado.get(1).titulo);
consola
[{
"autor": "Cervantes",
"titulo": "El Quijote",
"precio": 33.5
}, {
"autor": "C. Jose Cela",
"titulo": "La Colmena",
"precio": 11.8
}, {
"autor": "C. Jose Cela",
"titulo": "San Camilo 1936",
"precio": 22.0
}]
La Colmena
b) Con un ArrayList, convirtiendo a JSON igual que con una clase, pero al deserializar con fromJSON hay un
problema, no se puede usar un ArrayList como tipo de dato, así que hay que sacar el "tipo de dato" del
ArrayList con la clase TypeToken de GSON y la clase Type de Java
Los import de estas dos clases son:
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
๏ Para crear PF vamos a usar una utilidad de mercado llamada iText
๏ Antes de empezar con el código, hemos de agregar las librerías necesarias.
๏ Vamos a aprovechar y a explicar como crear un proyecto Maven, para aprovechar sus dependencias y ver otro
modo de añadir librerías a un proyecto:
๏ Elegir New Project - Maven - Next
๏ En la pantalla siguiente, escribir:
✦ Groupid : com.itextpdf (es donde luego vamos a montar las dependencias externas)
✦ ArtifactId: el nombre de nuestro Artefacto. Puede ser el mismo que el proyecto
✦ Version: dejar la que sale por defecto o cambiar si se desea
✦ Elegir Next
Crear PDF
Añadir librerias en un proyecto MAVEN (con IDE IntelliJ)
27
Crear un PDF desde un programa JAVA
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
• En la pantalla siguiente, escribir:
✦ ProjectName : el nombre de nuestro proyecto, con dominio si se desea (puede se igual que el Artefacto)
✦ ProjectLocation: ubicación del proyecto
✦ Finish
Puede aparecer ahora un mensaje como :
Activar los cambios como se desee, de las dos opciones ofrecidas
Crear PDF 28
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itextpdf</groupId> // Estas tres lineas son la referencia, no de una dependencia, sino del
<artifactId>jyocPdfJava</artifactId> // propio programa principal
<version>1.0-SNAPSHOT</version>
// Para añadir dependencias, consultar al proveedor para informarse de los nombres y versiones correctos de las librerias a añadir
// (no suelen coincidir con los nombres de los ficheros JAR)
<dependencies>
<dependency> // PRIMERA DEPENDENCIA
<groupId>com.itextpdf</groupId> // groupId : debe coincidir con el identificado al crear el proyecto
<artifactId>kernel</artifactId> // artifactId : es aqui el NOMBRE de la libreria que queremos importar
<version>7.0.2</version> // version : es la version que vamos a utilizar
</dependency>
<dependency> // RESTO DE DEPENDENCIAS . Igual que la anterior
<groupId>com.itextpdf</groupId>
<artifactId>io</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>forms</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>pdfa</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>pdftest</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.18</version>
</dependency>
</dependencies>
</project>
Crear PDF 29
• Aparece también una ventana con el fichero de configuración de dependencias. Aquí hemos de incluir la información
de las librerías que deseamos configurar para el proyecto, de modo que se actualicen automáticamente.
Aquí se muestra el contenido del fichero con las dependencias ya añadidas. El fichero inicialmente tiene un contenido
que se marca en blanco. En la representación se explica cómo se configura cada librería añadida como dependencia.
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
(continua… )
Crear PDF 30
import com.itextpdf.io.font.FontConstants;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import java.io.IOException;
public class CrearPdfEnJava {
public static final String FICHERODESTINO = "MiPrimerPdf.pdf";
public final String IMAG1 = "Logo_JYOC_crema_pq.png";
public static final String FICHCSV = "capitales.csv";
public static void main(String args[]) throws IOException {
// Si el nombre del fichero incluye path, añadir la linea siguiente
// para asegurar que se crean los directorios intermedios para crear el fichero
// new File(FICHERODESTINO).getParentFile().mkdirs();
new CrearPdfEnJava().crearPdf(FICHERODESTINO);
}
public void crearPdf(String dest) throws IOException {
// Inicializar PDFwriter
PdfWriter writer = new PdfWriter(dest);
// Inicializar PDFdocument
PdfDocument pdf = new PdfDocument(writer);
// Inicializar document
Document document = new Document(pdf);
// aplicamos margenes al document
document.setMargins(20, 20, 20, 20);
// AÑADIR TEXTOS *********************************************************
// Añadir un par de lineas (párrafos)
document.add(new Paragraph("Una primera linea en el documento"));
document.add(new Paragraph("Una segundfa linea que quede debajo”));
// Crear una PdfFont
PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
// Aplicar una fuente a un Paragraph
document.add(new Paragraph("Ejemplo de lista con viñetas:").setFont(font));
(continua) ➡
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF
// AÑADIR LISTAS ****************************************************
// Crear una List, un grupo de lineas con un font, tamaño
// y caracteristicas compartidas, incluidas viñetas
List list = new List()
.setSymbolIndent(12)
.setListSymbol("u2022")
.setFont(font);
// Añadir elementos (ListItem) a la lista
list.add(new ListItem("Con cien cañones por banda"))
.add(new ListItem("viento en popa a toda vela"))
.add(new ListItem("no corta el mar sino vuela"))
.add(new ListItem("un velero bergantín"));
// Agregar la lista al document
document.add(list);
// AÑADIR UNA IMAGEN ********************************
// Crear una imagen y añadirla a un parrafo
Image im1 = new Image(ImageDataFactory.create(IMAG1));
Paragraph p = new Paragraph("Una imagen...”)
.add(im1)
.add(" ...encuadrada entre dos lineas.");
// Agregar el parrafo con imagen al document
document.add(p);
PDF Resultante del ejercicio:
Crear PDF 31
TemariodecursoJavaSE©IñakiMartín

15.- Ficheros XML, JSON, PDF Crear PDF 32
// AÑADIR UNA TABLA *********************************************************
PdfFont fontNormal = PdfFontFactory.createFont(FontConstants.HELVETICA);
PdfFont fontbold = PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD);
// Crear el elemento table, en el constructor recibe un array de float con
// tantos elementos como columnas de la tabla
// El valor indica la proporcionalidad del tamaño de las columnas
Table tabla = new Table(new float[]{3, 1, 1, 1});
tabla.setWidthPercent(100);
String[][] textos = {{"Capital", "Provincia", "Población", "Idioma"},
{"Vitoria", "Alava", "244600", "Euskera"},
{"Bilbao", "Vizcaya", "345000", "Euskera"},
{"Donostia", "Guipuzcoa", "186000", "Euskera"},
{"Pamplona", "Navarra", "201000", "Euskera"},
{"Logroño", "La Rioja", "150000", "Castellano"},
{"Oviedo", "Asturias", "220000", "Castellano (Bable)"}};
procesarTabla(tabla, textos[0], fontbold, true);
for (int i = 1; i < textos.length; i++) {
procesarTabla(tabla, textos[i], fontNormal, true);
}
document.add(tabla);
// Cerrar document
document.close();
}
public void procesarTabla(Table pTabla, String[] pLinea, PdfFont pFont, boolean pEsCabecera) {
for (int j = 0; j < pLinea.length; j++) {
// Se crea la celda a añadir
Cell celda = new Cell();
celda.add(new Paragraph(pLinea[j]).setFont(pFont));
// Añadimos la celda a la tabla, aunque se usan metodos diferentes si la celda es
// una fila de cabecera o no.
if (pEsCabecera) {
pTabla.addHeaderCell(celda);
} else {
pTabla.addCell(celda);
}
}
}

Más contenido relacionado

La actualidad más candente

Csi: siempre quisiste ser forense
Csi: siempre quisiste ser forenseCsi: siempre quisiste ser forense
Csi: siempre quisiste ser forenseEventos Creativos
 
Seguridad en PDF - Adobe ¬¬
Seguridad en PDF - Adobe ¬¬Seguridad en PDF - Adobe ¬¬
Seguridad en PDF - Adobe ¬¬Alejandro Ramos
 
Curso scjp 30 navegacion de archivos e io
Curso scjp 30   navegacion de archivos e ioCurso scjp 30   navegacion de archivos e io
Curso scjp 30 navegacion de archivos e ioprogramadorjavablog
 
PERSISTENCIA BASADA EN ARCHIVOS
PERSISTENCIA BASADA EN ARCHIVOSPERSISTENCIA BASADA EN ARCHIVOS
PERSISTENCIA BASADA EN ARCHIVOSDarwin Durand
 
Serializacion de objetos en java
Serializacion de objetos en javaSerializacion de objetos en java
Serializacion de objetos en javaHugo Nugra
 
Serializacion de objetos en java
Serializacion de objetos en javaSerializacion de objetos en java
Serializacion de objetos en javaHugo Nugra
 
Persistencia en Java - Serialización
Persistencia en Java - SerializaciónPersistencia en Java - Serialización
Persistencia en Java - SerializaciónCarlos Hernando
 
Flujos de Entrada y Salida en Java
Flujos de Entrada y Salida en JavaFlujos de Entrada y Salida en Java
Flujos de Entrada y Salida en JavaIngeniería Nica
 
Curso scjp 30 navegacion de archivos e io
Curso scjp 30   navegacion de archivos e ioCurso scjp 30   navegacion de archivos e io
Curso scjp 30 navegacion de archivos e ioprogramadorjavablog
 
Fichero c y c++
Fichero c y c++Fichero c y c++
Fichero c y c++mauro0210
 
Manejo de archivos en JAVA
Manejo de archivos en JAVAManejo de archivos en JAVA
Manejo de archivos en JAVAMichelle Torres
 
Entrada y Salida de datos en Java
Entrada y Salida de datos en JavaEntrada y Salida de datos en Java
Entrada y Salida de datos en Javakunno10
 
Suarez l 2001 el paquete java io
Suarez l 2001 el paquete java ioSuarez l 2001 el paquete java io
Suarez l 2001 el paquete java ioLuis Lopez Ac
 

La actualidad más candente (18)

Archivos
ArchivosArchivos
Archivos
 
Csi: siempre quisiste ser forense
Csi: siempre quisiste ser forenseCsi: siempre quisiste ser forense
Csi: siempre quisiste ser forense
 
Seguridad en PDF - Adobe ¬¬
Seguridad en PDF - Adobe ¬¬Seguridad en PDF - Adobe ¬¬
Seguridad en PDF - Adobe ¬¬
 
Curso scjp 30 navegacion de archivos e io
Curso scjp 30   navegacion de archivos e ioCurso scjp 30   navegacion de archivos e io
Curso scjp 30 navegacion de archivos e io
 
PERSISTENCIA BASADA EN ARCHIVOS
PERSISTENCIA BASADA EN ARCHIVOSPERSISTENCIA BASADA EN ARCHIVOS
PERSISTENCIA BASADA EN ARCHIVOS
 
Serializacion de objetos en java
Serializacion de objetos en javaSerializacion de objetos en java
Serializacion de objetos en java
 
Serializacion de objetos en java
Serializacion de objetos en javaSerializacion de objetos en java
Serializacion de objetos en java
 
Unidad 6: Flujos y Archivos Ejercicio 4
Unidad 6: Flujos y Archivos Ejercicio 4Unidad 6: Flujos y Archivos Ejercicio 4
Unidad 6: Flujos y Archivos Ejercicio 4
 
Grupo nro4ficheros
Grupo nro4ficherosGrupo nro4ficheros
Grupo nro4ficheros
 
Persistencia en Java - Serialización
Persistencia en Java - SerializaciónPersistencia en Java - Serialización
Persistencia en Java - Serialización
 
Flujos y archivos
Flujos y archivosFlujos y archivos
Flujos y archivos
 
Flujos de Entrada y Salida en Java
Flujos de Entrada y Salida en JavaFlujos de Entrada y Salida en Java
Flujos de Entrada y Salida en Java
 
Curso scjp 30 navegacion de archivos e io
Curso scjp 30   navegacion de archivos e ioCurso scjp 30   navegacion de archivos e io
Curso scjp 30 navegacion de archivos e io
 
Fichero c y c++
Fichero c y c++Fichero c y c++
Fichero c y c++
 
Manejo de archivos en JAVA
Manejo de archivos en JAVAManejo de archivos en JAVA
Manejo de archivos en JAVA
 
Entrada y Salida de datos en Java
Entrada y Salida de datos en JavaEntrada y Salida de datos en Java
Entrada y Salida de datos en Java
 
Tema1oficial
Tema1oficialTema1oficial
Tema1oficial
 
Suarez l 2001 el paquete java io
Suarez l 2001 el paquete java ioSuarez l 2001 el paquete java io
Suarez l 2001 el paquete java io
 

Similar a Jyoc java-cap15 persistencia. ficheros xml, j son y pdf

XML con J de JDOM
XML con J de JDOMXML con J de JDOM
XML con J de JDOM12345678a
 
Procesamiento de XML en C#
Procesamiento de XML en C#Procesamiento de XML en C#
Procesamiento de XML en C#Jordan-P
 
programacion para la web (Dom)
programacion para la web (Dom)programacion para la web (Dom)
programacion para la web (Dom)Ivana Ibarra
 
6. Utilización del modelo de objetos del documento (DOM)
6. Utilización del modelo de objetos del documento (DOM)6. Utilización del modelo de objetos del documento (DOM)
6. Utilización del modelo de objetos del documento (DOM)Laura Folgado Galache
 
Entidades en drupal 8
Entidades en drupal 8Entidades en drupal 8
Entidades en drupal 8Atenea tech
 
Desarrollo de Aplicaciones Web II - Sesión 03 - Formularios y Validaciones
Desarrollo de Aplicaciones Web II - Sesión 03 - Formularios y ValidacionesDesarrollo de Aplicaciones Web II - Sesión 03 - Formularios y Validaciones
Desarrollo de Aplicaciones Web II - Sesión 03 - Formularios y ValidacionesDidier Granados
 
Tema 3 xml processing ap is
Tema 3   xml processing ap isTema 3   xml processing ap is
Tema 3 xml processing ap isxkorpium
 
Entidades en drupal 8
Entidades en drupal 8Entidades en drupal 8
Entidades en drupal 8Atenea tech
 
Dom
DomDom
DomPEPE
 
Javascript Clásico
Javascript ClásicoJavascript Clásico
Javascript ClásicoIrontec
 

Similar a Jyoc java-cap15 persistencia. ficheros xml, j son y pdf (20)

XML con J de JDOM
XML con J de JDOMXML con J de JDOM
XML con J de JDOM
 
Clase 8 Manipulación del DOM
Clase 8 Manipulación del DOMClase 8 Manipulación del DOM
Clase 8 Manipulación del DOM
 
Apuntes: Manejar el DOM con JavaScript
Apuntes: Manejar el DOM con JavaScriptApuntes: Manejar el DOM con JavaScript
Apuntes: Manejar el DOM con JavaScript
 
Procesamiento de XML en C#
Procesamiento de XML en C#Procesamiento de XML en C#
Procesamiento de XML en C#
 
programacion para la web (Dom)
programacion para la web (Dom)programacion para la web (Dom)
programacion para la web (Dom)
 
6. Utilización del modelo de objetos del documento (DOM)
6. Utilización del modelo de objetos del documento (DOM)6. Utilización del modelo de objetos del documento (DOM)
6. Utilización del modelo de objetos del documento (DOM)
 
Entidades en drupal 8
Entidades en drupal 8Entidades en drupal 8
Entidades en drupal 8
 
Dom JavaScript
Dom JavaScriptDom JavaScript
Dom JavaScript
 
Guiajs2
Guiajs2Guiajs2
Guiajs2
 
Lectura de un archivo xml de manera local en wp
Lectura de un archivo xml de manera local en wpLectura de un archivo xml de manera local en wp
Lectura de un archivo xml de manera local en wp
 
Desarrollo de Aplicaciones Web II - Sesión 03 - Formularios y Validaciones
Desarrollo de Aplicaciones Web II - Sesión 03 - Formularios y ValidacionesDesarrollo de Aplicaciones Web II - Sesión 03 - Formularios y Validaciones
Desarrollo de Aplicaciones Web II - Sesión 03 - Formularios y Validaciones
 
Doctrine2 sf2Vigo
Doctrine2 sf2VigoDoctrine2 sf2Vigo
Doctrine2 sf2Vigo
 
DOM HTML Javascript
DOM HTML JavascriptDOM HTML Javascript
DOM HTML Javascript
 
Apuntes de DTD
Apuntes de DTDApuntes de DTD
Apuntes de DTD
 
Tema 3 xml processing ap is
Tema 3   xml processing ap isTema 3   xml processing ap is
Tema 3 xml processing ap is
 
Dom
DomDom
Dom
 
Entidades en drupal 8
Entidades en drupal 8Entidades en drupal 8
Entidades en drupal 8
 
Exposicion
ExposicionExposicion
Exposicion
 
Dom
DomDom
Dom
 
Javascript Clásico
Javascript ClásicoJavascript Clásico
Javascript Clásico
 

Más de Jyoc X

Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc X
 
Jyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc X
 
Jyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzadoJyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzadoJyoc X
 
Jyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc X
 
Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc X
 
Jyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc X
 
Jyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc X
 
Jyoc java-cap12 excepciones
Jyoc java-cap12 excepcionesJyoc java-cap12 excepciones
Jyoc java-cap12 excepcionesJyoc X
 
Jyoc java-cap11 colecciones
Jyoc java-cap11 coleccionesJyoc java-cap11 colecciones
Jyoc java-cap11 coleccionesJyoc X
 
Jyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc X
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc X
 
Jyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc X
 
Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc X
 
Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc X
 
Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc X
 
Jyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc X
 
Jyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcacionesJyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcacionesJyoc X
 
Jyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc X
 
Jyoc java-cap16 persistencia. bases de datos
Jyoc java-cap16 persistencia. bases de datosJyoc java-cap16 persistencia. bases de datos
Jyoc java-cap16 persistencia. bases de datosJyoc X
 

Más de Jyoc X (19)

Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unit
 
Jyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc java-cap22 seguridad
Jyoc java-cap22 seguridad
 
Jyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzadoJyoc java-cap21 jse avanzado
Jyoc java-cap21 jse avanzado
 
Jyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilas
 
Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)
 
Jyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fx
 
Jyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc java-cap13 recursividad
Jyoc java-cap13 recursividad
 
Jyoc java-cap12 excepciones
Jyoc java-cap12 excepcionesJyoc java-cap12 excepciones
Jyoc java-cap12 excepciones
 
Jyoc java-cap11 colecciones
Jyoc java-cap11 coleccionesJyoc java-cap11 colecciones
Jyoc java-cap11 colecciones
 
Jyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumerados
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios poo
 
Jyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetos
 
Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase string
 
Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)
 
Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)
 
Jyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc java-cap03 bucles
Jyoc java-cap03 bucles
 
Jyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcacionesJyoc java-cap02 bifurcaciones
Jyoc java-cap02 bifurcaciones
 
Jyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salida
 
Jyoc java-cap16 persistencia. bases de datos
Jyoc java-cap16 persistencia. bases de datosJyoc java-cap16 persistencia. bases de datos
Jyoc java-cap16 persistencia. bases de datos
 

Último

Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxpabonheidy28
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELmaryfer27m
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxazmysanros90
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx241522327
 
El uso de las tic en la vida ,lo importante que son
El uso de las tic en la vida ,lo importante  que sonEl uso de las tic en la vida ,lo importante  que son
El uso de las tic en la vida ,lo importante que son241514984
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxNombre Apellidos
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024GiovanniJavierHidalg
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaarkananubis
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxJOSEFERNANDOARENASCA
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx241523733
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxaylincamaho
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...FacuMeza2
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.241514949
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativaAdrianaMartnez618894
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA241531640
 
Mapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMidwarHenryLOZAFLORE
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdfIsabellaMontaomurill
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadMiguelAngelVillanuev48
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafiosFundación YOD YOD
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptMiguelAtencio10
 

Último (20)

Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docx
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFEL
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptx
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx
 
El uso de las tic en la vida ,lo importante que son
El uso de las tic en la vida ,lo importante  que sonEl uso de las tic en la vida ,lo importante  que son
El uso de las tic en la vida ,lo importante que son
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en mina
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptx
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativa
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
 
Mapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptx
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdf
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidad
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafios
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.ppt
 

Jyoc java-cap15 persistencia. ficheros xml, j son y pdf

  • 1. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF TEMARIO DE CURSO PROGRAMACIÓN JAVA SE CAPÍTULO 15 PERSISTENCIA. FICHEROS XML, JSON, PDF © Iñaki Martín Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional.
  • 2. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (I) Crear un fichero XML usando DOM 2 ๏ DOM (Document Object Model) es un estándar de la WWW, que define cómo representar documentos HTML, XHTML y XML. En base, define qué tipo de etiquetas y atributos puede haber, en qué orden y con que estructura ๏ Java posee clases para trabajar con ficheros XML o HTML tratándolos como objetos DOM. La mecánica es leer el fichero HTML o XML y almacenarlo en un objeto Document, y procesar este, o escribir un objeto Document en un fichero XML/HTML ๏ Para el procesamiento de ficheros DOM se usan, entre otras, las clases Node, Element, y NodeList. ๏ Antes de seguir es importante que se entienda la diferencia entre dichas clases: ‣ Un Node es cualquier objeto que haya en un documento DOM. ‣ Un Element es un tipo específico de Node, al igual que hay otros muchos tipos de nodos (textos de nodo, comentarios, el propio Document entero es un tipo -Document-) ‣ Un documento DOM consiste en una jerarquía de nodos en modo árbol, en el que cada nodo tiene hermanos, un padre, o hijos. Un NodeList es un conjunto de nodos, que pueden definirse a través de “hijos de X”, “todos los de nombre X” , etc (todo ello con métodos que veremos más adelante) ๏ La página siguiente contiene un resumen de las clases y métodos básicos para trabajar con DOM Ejemplo DOM: estructura DOM de un fichero HTML:
  • 3. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (III) 3 Métodos de uso en DOM (para crear XML) CLASE DEVUELVE METODOS DESCRIPCION Document Node getDocumentElement() Devuelve el nodo raiz de un documento nivel1 = miDocDom.createElement("personal"); Document Node createElement("texto") Crea un nodo cuyo nombre es el texto del parametro nivel11 = miDocDom.createElement("empleado"); Node void setAttribute("texto", "contenido") Crea, en el Element aplicado, un atributo de nombre "texto" con valor "contenido" ((Element) unnodo).setAttribute("codigoEmp", "2323"); Document Node createTextNode("texto") Crea un nodo de texto (el valor de una etiqueta) nodotexto = miDocDom.createTextNode("Pedro"); Node void appendChild( otronodo ) Añade otroNodo como un nodo hijo del nodo llamante unnodo.appendChild(sunodohijo); Métodos de uso en DOM (para leer XML) CLASE DEVUELVE METODOS DESCRIPCION Document Node getDocumentElement() Devuelve el nodo raiz de un documento nivel1 = miDocDom.createElement("personal"); Node NodeList getElementsByTagName("texto") Devuelve una lista con los nodos que tienen por nombre "texto" NodeList listaDeNodosDeEmpleados = nodoRaiz.getElementsByTagName("empleado"); NodeList int getLength() Devuelve el tamaño de una NodeList int m listaNodosHijosDeEmpleado.getLength(); Node NodeList getChildNodes() Devuelve una lista con los nodos hijos del nodo al que se aplica el metodo NodeList listaNodosHijos = nodoEmpleado.getChildNodes(); NodeList Node item( num ) Devuelve el nodo num-esimo de la lista de nodos a la que se aplica el metodo Node dato = listaNodos.item(m); Node String getNodeName() Devuelve el nombre del nodo al que se aplica el metodo if (dato.getNodeName().equals("nombre")) Node Node getFirstChild() Devuelve el primer hijo del nodo al que se aplica el metodo Node datoContenido = dato.getFirstChild(); Node String getNodeValue() Devuelve el valor (el contenido) del nodo al que se aplica el metodo String atrib= nodo.getAttributes().getNamedItem("cod").getNodeValue() Node NamedNo deMap getAttributes() Devuelve todos los atributos de nodo al que se aplica el metodo NamedNodeMap mapanodo = nodoEmpleado.getAttributes() NamedNod eMap Node getNamedItem( texto ) Devuelve el elemento llamado "texto" de los que existen en la colección Node unnodo = nodoEmpleado.getAttributes().getNamedItem("codDptoPertenecia")
  • 4. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (IV) 4 public class Empleado { String codigoEmpleado; String nombreEmpleado; String apellidoEmpleado; String codDptoPertenecia; public Empleado() { } public Empleado(String codigoEmpleado, String nombreEmpleado, String apellidoEmpleado, String codDptoPertenecia) { this.codigoEmpleado = codigoEmpleado; this.nombreEmpleado = nombreEmpleado; this.apellidoEmpleado = apellidoEmpleado; this.codDptoPertenecia = codDptoPertenecia; } public String getCodigoEmpleado() { return codigoEmpleado; } public String getNombreEmpleado() { return nombreEmpleado; } public String getApellidoEmpleado() {return apellidoEmpleado; } public String getCodDptoPertenecia() { return codDptoPertenecia; } public void setCodigoEmpleado(String codigoEmpleado) { this.codigoEmpleado = codigoEmpleado; } public void setNombreEmpleado(String nombreEmpleado) { this.nombreEmpleado = nombreEmpleado; } public void setApellidoEmpleado(String apellidoEmpleado) { this.apellidoEmpleado = apellidoEmpleado; } public void setCodDptoPertenecia(String codDptoPertenecia) { this.codDptoPertenecia = codDptoPertenecia; } } ๏ Como siempre, se ve todo mucho mejor en un ejemplo práctico : vamos a guardar, en un ficheroXML, una lista de objetos de las clase Empleado ๏ Empleado es una clase POJO normal (POJO es una clase que solo tiene atributos, constructor completo, getters y setters ๏ Es obligatorio que tenga un constructor vacío: Fichero XML objetivo del ejemplo <datosDePersonal> // raiz <personal> <empleado codigoEmp="c10" codDeptoPertenencia="d10"> <nombre>Pepe</nombre> <apellido>Perez</apellido> </empleado> <empleado codigoEmp="c11" codDeptoPertenencia="d20"> <nombre>Eva</nombre> <apellido>Lopez</apellido> </empleado> </personal> </datosDePersonal>
  • 5. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Desde el main de nuestro proyecto se invocan a dichos métodos Ficheros XML con DOM (IV) 5 public class EjercicioDOM { ArrayList<Empleado> listaEmpleados; public static void main(String[] args) { Document miDocumentoDom; GestionDOM gd = new GestionDOM(); listaEmpleados = new ArrayList<>(); listaEmpleados.add(new Empleado(“c10","Pepe", "Perez", “d10")); listaEmpleados.add(new Empleado("c11","Eva", "Lopez", “d20”)); // Creamos un documento DOM llamado miDocumentoDom con el arraylist leido miDocumentoDom = gd.crearDocumentoDOMcondatosJava(listaEmpleados); // creamos un fichero DOM1.xml con el documento miDocumentoDom gd.guardarDocumentoDOMcomoXML( miDocumentoDom, "DOM1.xml" ); // Creamos un documento DOM parseando un fichero XML existemte miDocumentoDom = gd.leerFicheroXmlEnDocumentDOM("DOM1.xml"); // Creamos nuevamente el arraylist con el DOM parseado de DOM1.xml listaEmpleados = gd.crearClasesJavaDesdeDocumentDOM(miDocumentoDom); } } 1 2 3 4 ๏ Para este ejercicio proponemos una solución modularizada, con cuatro métodos que hagan las siguientes cosas : dos son para crear un fichero XML, y otros dos para leer un fichero XML ya existente): • crearDocumentoDOMcondatosJava() : desde objetos Java, se crea un objeto Document, que tiene ya la estructura XML • guardarDocumentoDOMcomoXML() : el objeto Document ya creado, se escribe en un fichero de disco • leerFicheroXmlEnDocumentDOM() : lee un fichero de disco con contenido XML y lo almacena en un objeto Document • crearClasesJavaDesdeDocumentDOM() : desde un objeto Document, se crean nuevamente las clases Java originales
  • 6. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (V) public class GestionDOM { Node nodo_personal, nodo_empleado, nodo_raiz,nodo_nombre, nodo_apellidos, nodo_nombre_texto, nodo_apellidos_texto; public Document crearDocumentoDOMcondatosJava(ArrayList<Empleado> listaEmp) { Document miDocDom; //Objeto Document que almacena el DOM del XML seleccionado. try { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); DOMImplementation implementation = builder.getDOMImplementation(); String nombreDelNodoRaiz = "datosDePersonal"; miDocDom = implementation.createDocument(null, nombreDelNodoRaiz, null); miDocDom.setXmlVersion("1.0"); //-- Crear los nodos de todas las etiquetas generales nodo_raiz = miDocDom.getDocumentElement(); nodo_personal = miDocDom.createElement("personal"); // recorrer el arraylist de empleados for (Empleado em : listaEmp) { //-- Crear los nodos de todas las etiquetas del empleado nodo_empleado = miDocDom.createElement("empleado"); nodo_nombre = miDocDom.createElement("nombre"); nodo_apellidos = miDocDom.createElement("apellidos"); //-- Crear los nodos de texto con los valores de cada empleado nodo_nombre_texto = miDocDom.createTextNode(em.getNombreEmpleado()); nodo_apellidos_texto = miDocDom.createTextNode(em.getApellidoEmpleado()); //-- Añade atributos como elementos de texto, esto no crea nodos, modifica los ya creados ((Element) nodo_empleado).setAttribute("codigoEmp", em.getCodigoEmpleado()); ((Element) nodo_empleado).setAttribute("codDptoPertenencia", em.getCodDptoPertenecia() + ""); //-- Añadir cada nodo a su padre nodo_nombre.appendChild(nodo_nombre_texto); nodo_apellidos.appendChild(nodo_apellidos_texto); nodo_empleado.appendChild(nodo_nombre); nodo_empleado.appendChild(nodo_apellidos); nodo_personal.appendChild(nodo_empleado); } // Se añade el nodo personal a nodo raiz, no se hace dentro del for, pues hay que meter todos los empleados // en la etiqueta personal.... nodo_raiz.appendChild(nodo_personal); // se devuelve finalmente el document creado return miDocDom; } catch (Exception e) { return null; } } 6 1 <datosDePersonal> // raiz <personal> <empleado codigoEmp="c10" codDeptoPertenencia="d10"> <nombre>Pepe</nombre> <apellido>Perez</apellido> </empleado> <empleado codigoEmp="c11" codDeptoPertenencia="d20"> <nombre>Eva</nombre> <apellido>Lopez</apellido> </empleado> </personal> </datosDePersonal>
  • 7. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (VI) public void guardarDocumentoDOMcomoXML(Document pdoc, String nombreFicheroXML) { try { //guardar el documento DOM como un fichero ; //Crea un fichero llamado salida.xml File archivo_xml = new File(nombreFicheroXML); //Especifica el formato de salida OutputFormat format = new OutputFormat(pdoc); //Especifica que la salida esté indentada. format.setIndenting(true); //Escribe el contenido en el FILE XMLSerializer serializer = new XMLSerializer(new FileOutputStream(archivo_xml), format); serializer.serialize(pdoc); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 7 2 public Document leerFicheroXmlEnDocumentDOM(String fichero) { Document document = null; try { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); document = builder.parse(new FileInputStream(fichero)); } catch (Exception e1) { e1.printStackTrace(); } return document; } 3
  • 8. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (VII) public ArrayList<Empleado> crearClasesJavaDesdeDocumentDOM(Document document) { String nombreDelNodoRaiz, nombre, apellidos, cod, dep; ArrayList<Empleado> alistaEmpleados = new ArrayList<>(); nodo_raiz = document.getDocumentElement(); // sacar del document el nodo raiz nombreDelNodoRaiz = nodo_raiz.getNodeName(); // sacar el nombre del nodo raiz // cogemos los hijos directos de raiz NodeList listaHijosRaiz = ((Element)nodo_raiz).getElementsByTagName("personal"); // como solo debe tener un hijo, este es personal nodo_personal = listaHijosRaiz.item(0); Element elemento_personal = (Element) nodo_personal; // cogemos los hijos directos de personal NodeList listaEmpleados = elemento_personal.getElementsByTagName("empleado"); for (int t = 0; t < listaEmpleados.getLength(); t++) { nodo_empleado = listaEmpleados.item(t); nombre = getValorNodoHijoSimple("nombre", nodo_empleado); apellidos = getValorNodoHijoSimple("apellidos", nodo_empleado); cod = getValorAtributo("codigoEmp", nodo_empleado); dep = getValorAtributo("codDptoPertenencia", nodo_empleado); Empleado emp = new Empleado(cod, nombre, apellidos, Integer.parseInt(dep)); alistaEmpleados.add(emp); } return alistaEmpleados; } 8 4 Tambien puede ser util, tras extraer el nodo raiz, usar el método normalize(), que elimina los nodos vacíos del XML y otros problemas de estructura: nodo_raiz.normalize(); (continua) ➡
  • 9. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Ficheros XML con DOM (VIII) public String getValorNodoHijoSimple(String etiquetaABuscar, Element elementoPadre) { String resultado = ""; // sacar una lista de todos los nodo-etiqueta que se llame "etiquetaABuscar" y sea hijo de "elementoPadre" // con el ejemplo, esto da una lista de elementos <nombre> NodeList listaNodosHijos = elementoPadre.getElementsByTagName(etiquetaABuscar); // sacar el unico nodo-etiqueta que tiene esa lista (se sabe que el nodo es simple) // con el ejemplo, esto da el unico elemento <nombre> que existe Node nodo = listaNodosHijos.item(0); // sacar del nodo-etiqueta su único hijo, que es el CONTENIDO de la etiqueta (que sigue siendo un nodo...) // en el ejemplo, es Pepe, pero con formato de nodo if (nodo != null) { Node contenido = nodo.getFirstChild(); // sacar del nodo-contenido su valor // en el ejemplo, ahora si, la cadena "Pepe" resultado = contenido.getNodeValue(); } return resultado; } // Version sobrecargada, con Node en vez de Element public String getValorNodoHijoSimple(String etiquetaABuscar, Node nodoPadre) { Element elementoPadre = (Element) nodoPadre; return getValorNodoHijoSimple(etiquetaABuscar, elementoPadre); } public String getValorAtributo(String atributoABuscar, Node nodoPadre) { String resultado = ""; NamedNodeMap nnm = nodoPadre.getAttributes(); Node attr = nnm.getNamedItem(atributoABuscar); if (attr != null) { resultado = attr.getNodeValue(); } return resultado; } 9 4 (continuación )
  • 10. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF ๏ Para la gestión de estos eventos, es necesario crear una clase propia heredera de DefaultHandler (un Handler es, en jerga informática, un tipo de objetos que “manejan” o “manipulan” información) Esta clase dispone de varios métodos, de los que hemos de sobrescribir, como poco, los siguientes: - startDocument(): se “dispara” al comenzar a leer el documento xml. - endDocument(): se “dispara” al finalizar de leer el documento xml. - startElement(): se “dispara” al leer una etiqueta de comienzo de elemento Aquí se deben leer los atributos de las etiquetas. Cuando el analizador encuentra una etiqueta de inicio llama a startElement, indicando el nombre de la etiqueta. Pero cuidado que no indica la etiqueta padre, así que no es fácil saber dónde esta la etiqueta encontrada. La mejor solución es tener una/s variables que indiquen por dónde va pasando el analizador. - endElement(): se “dispara” al leer una etiqueta de fin de elemento. - characters(): se “dispara” al encontrar una cadena de texto (cuidado, pues puede haber cadenas ocultas). Cuando el analizador encuentra un texto dentro de una etiqueta, llama al método characters. Como no se sabe qué texto se esta leyendo (pues no se indica la etiqueta donde se encuentra el texto) es útil lo dicho antes, que se haya guardado previamente al pasar por el startElement qué etiqueta se esta procesando El método characters recibe tres parametros: (char[] chars, int start, int length) • chars indica la cadena global que esta procesando el analizador, • Start donde comienza el texto que esta leyendo ahora y • Length que tamaño tiene el texto. Por lo tanto, lo que se hace es crear un String pasándole esos mismos tres parámetros (si, existe un constructor de String con esos datos) y así recogemos el texto de la etiqueta 10 ๏ Otro mecanismo para leer XML desde Java es usando SAX (Simple API for XML). SAX fue el primer “parseador” de XML adoptado como API para XML en Java, y tiene ventajas e inconvenientes frente a DOM u otros mecanismos, que veremos más adelante (un “parseador”, parser en ingles, es un programa que “traduce” algo siguiendo unas de análisis sintáctico). ๏ SAX es un parser con acceso en serie (va recorriendo el xml poco a poco) y basado en eventos (va llamando a eventos según encuentra determinadas partes del xml, como el principio de etiqueta, fin de etiqueta, texto, ….) Leer Xml con SAX desde Java SAX en Java (I) 1
  • 11. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 11 public class Alumno { private String nombre, apellidos; private String id; private double nota; public Alumno() { } public Alumno(String nombre, String id, double nota) { this.nombre = nombre; this.id = id; this.nota = nota; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getId() { return id; } public void setId(String id) { this.id = id; } public double getNota() { return nota; } public void setNota(double nota) { this.nota = nota; } public String toString() { return “{“+"nombre="+nombre+","+apellido+": id=“+ id +":"+"nota="+nota+"}"; } } SAX en Java (II) <clase> <alumno id = "33"> <nombre>Ana</nombre> <apellido>Arranz</apellido> <nota>8</nota> </alumno> <alumno id = "17"> <nombre>Pepe</nombre> <apellido>Perez</apellido> <nota>5</nota> </alumno> </clase> ๏ Clase Alumno, que será la que se use para crear un arrayList tras leer lo que contiene el xml ๏ Fichero XML que deseamos leer ๏ El ejemplo siguiente explica mejor como leer un xml y otros métodos que se usan en el proceso:
  • 12. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 12 public class MiHandlerSax extends DefaultHandler { // CREA EL HANDLER QUE SE USA LUEGO PARA PARSEAR EL XML ArrayList<Alumno> listaAlumnos = new ArrayList<>(); Alumno unalumno; String etiquetaActual = ""; @Override public void startDocument() throws SAXException { // esto se ejecuta al comenzar a leer el documento. } @Override public void endDocument() throws SAXException { // esto se ejecuta al finalizar de leer el documento } @Override public void startElement(String uri, String localName, String qname, Attributes attributes) throws SAXException { // debemos guardarnos qué etiqueta estamos leyendo en cada momento etiquetaActual = qname; // al emplezar a leer cada elemento, solo me interesan los elementos que tienen atributos if (qname.equalsIgnoreCase("alumno")) { unalumno = new Alumno(); // como es comienzo de alumno, creo un nuevo alumno para darle datos String elId = attributes.getValue(“id"); // la etiqueta tiene atributo, asi que lo leo if (elId != null) unalumno.setId(elId); // nos aseguramos que el atributo tiene valor } } @Override public void characters(char[] ch, int start, int length) throws SAXException { // aqui entra en cuanto empieza a leerse un texo dentro de una etiqueta, // sabemos que etiqueta estamos leyendo, asi que cogemos el texto... String texto = new String(ch, start, length); // y lo asignamos al atributo del alumno que corresponde... if (etiquetaActual.equalsIgnoreCase("nombre")) { unalumno.setNombre(texto); } if (etiquetaActual.equalsIgnoreCase("id")) { unalumno.setId(texto); } if (etiquetaActual.equalsIgnoreCase("apellido")) { unalumno.setApellido(texto); } if (etiquetaActual.equalsIgnoreCase("nota")) { unalumno.setNota(Double.parseDouble(texto)); listaAlumnos.add(unalumno); // como la nota es la ultima etiqueta de un alumno, añadimos el alumno ya creado al arraylist } etiquetaActual = ""; } @Override public void endElement(String uri, String localName, String name){ // aqui entra en cuanto se leer una etiqueta de fin } public ArrayList<Alumno> getListaAlumnos() { return listaAlumnos; } } SAX en Java (III) //-- Tambien se pueden leer todos los atributos //—- y ver su nombre y valor for(int i=0;i<attributes.getLength();i++){ System.out.println("atributo: "+attributes.getQName(i)); System.out.println("valor: "+attributes.getValue(i)); } 1 ๏ Crear la clase propia que herede de DefaultHandler y que permita leer uno a uno todo el contenido del XML
  • 13. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 13 import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; public class PruebaSAX { public static void main(String[] args) { try { MiHandlerSax miHandler = miHandler = new MiHandlerSax(); // Creamos un analizador de XML con una fábrica de analizadores XMLReader xmlreader = XMLReaderFactory.createXMLReader(); // Añadimos nuestro handler al analizador xmlreader.setContentHandler(miHandler); // Analizamos con el analizador el xml deseado xmlreader.parse(new InputSource(new FileInputStream("alumnosxml.xml"))); // Probamos que el analizador ha leido el arraylist correctamente ArrayList<Alumno> listaalumnos = miHandler.getListaAlumnos(); for (Alumno a : listaalumnos) { System.out.println(a); } } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } consola {nombre=Ana: id=33:nota=8.0} {nombre=Pepe: id=17:nota=5.0} SAX en Java (IV) ๏ Una vez creado nuestro handler, usar la clase XMLReaderFactory para obtener un objeto de tipo XMLReader (un analizador) ๏ A ese analizador se le agrega como propiedad nuestro handler con el método setter setContentHandler() ๏ Finalmente se ejecuta el análisis con el método parse() pasándole el fichero XML a analizar 2 Cuidado: no podemos asumir alegremente que todo el texto de un elemento se lea con una sola llamada al método characters. Puede ocurrir, dependiendo de ciertas circunstancias, que el analizador llame dos o más veces al método para leer un texto, haciendo lecturas parciales en cada llamada. No es un comportamiento habitual, pero si así ocurre, la solución es ir acumulando el texto de distintas llamadas, y usar el método endElement para asegurar que se han acabado todas las llamadas a characters
  • 14. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 14SAX en Java (V) Escribir Xml con SAX desde Java ๏ Para escribir un fichero XML con herramientas SAX, se usan los siguientes pasos: 1. Crear un objeto de la clase XMLStreamWriter, que escribe textos con formato XML en un buffer, intermedio, ubicado en otro objeto, esta vez de la clase StringWriter 2. Crear el documento y añadir una etiqueta de cabecera xml, como por ejemplo <?xml version="1.0" ?> 3. Con writeStartElement() se crea una etiqueta de apertura, con el nombre que se le indica. 4. Con writeAttribute() añade un atributo a la última etiqueta que se haya abierto 5. Con writeCharacters() añade un contenido de texto a la última etiqueta que se haya abierto 6. Con writeEndElement() se añade una etiqueta de cierre, asociada a la última etiqueta que se haya abierto. Por ello no es necesario incluir un valor 7. Para anidar etiquetas, crear un writeStartElement() sin haber cerrado el anterior 8. Siempre añadir un writeEndDocument() para cerrar el documento se que se esta escribiendo // StringWriter crea objetos que procesan un buffer para construir cadenas StringWriter stringWriter = new StringWriter(); // XMLOutputFactory crea una fabrica de procesar archivos XML XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance(); // XMLStringWriter crea objetos capaces de almacenar etiquetas XML con estructura XMLStreamWriter xMLStreamWriter = xMLOutputFactory.createXMLStreamWriter(stringWriter); xMLStreamWriter.writeStartDocument(); xMLStreamWriter.writeStartElement("alumno"); xMLStreamWriter.writeStartElement("nombre"); xMLStreamWriter.writeCharacters(a.getNombre()); xMLStreamWriter.writeEndElement(); xMLStreamWriter.writeStartElement("apellido"); xMLStreamWriter.writeCharacters(a.getApellidos()); xMLStreamWriter.writeEndElement(); xMLStreamWriter.writeEndElement(); xMLStreamWriter.writeStartElement(“nombre"); xMLStreamWriter.writeAttribute("nacionalidad", “Española"); xMLStreamWriter.writeCharacters(a.getNombre()); xMLStreamWriter.writeEndElement(); xMLStreamWriter.writeEndDocument(); Etiqueta“alumno” Etiqueta “nombre” Etiqueta “apellido”
  • 15. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF writeStartElement() crea una etiqueta de apertura, con el nombre que se le indica Así, writeStartElement(“clase") crea la etiqueta <clase> Toda etiqueta de apertura ha de tener después su correspondiente etiqueta de cierre 15 public static void crearXmlConSax(ArrayList<Alumno> listaalumnos) { try { // StringWriter crea objetos que procesan un buffer para construir cadenas StringWriter stringWriter = new StringWriter(); // XMLOutputFactory crea una fabrica de procesar archivos XML XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance(); // XMLStringWriter crea objetos capaces de almacenar etiquetas XML con estructura XMLStreamWriter xMLStreamWriter = xMLOutputFactory.createXMLStreamWriter(stringWriter); xMLStreamWriter.writeStartDocument(); xMLStreamWriter.writeStartElement("clase"); for (Alumno a : listaalumnos) { // Recorremos el arraylist para crear cada alumno xMLStreamWriter.writeStartElement("alumno"); xMLStreamWriter.writeAttribute("id", a.getId()); xMLStreamWriter.writeStartElement("nombre"); xMLStreamWriter.writeCharacters(a.getNombre()); xMLStreamWriter.writeEndElement(); xMLStreamWriter.writeStartElement("apellido"); xMLStreamWriter.writeCharacters(a.getApellidos()); xMLStreamWriter.writeEndElement(); xMLStreamWriter.writeStartElement("nota"); xMLStreamWriter.writeCharacters(a.getNota() + ""); xMLStreamWriter.writeEndElement(); xMLStreamWriter.writeEndElement(); } xMLStreamWriter.writeEndDocument(); xMLStreamWriter.flush(); xMLStreamWriter.close(); // convertir el objeto stringWriter creado en un String String xmlString = stringWriter.getBuffer().toString(); stringWriter.close(); // escribir el String en un fichero xml fisico PrintWriter pw = new PrintWriter("alumnosDesdeSax.xml"); pw.print(xmlString); pw.close(); } catch (XMLStreamException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } SAX en Java (VI) Un writeStartElement() tras otro writeStartElement(), sin haber cerrado el anterior, anida la segunda etiqueta dentro de la anterior Un writeAttribute() añade un atributo a la última etiqueta que se haya abierto Un writeCharacters() añade un contenido de texto a la última etiqueta que se haya abierto Un writeEndElement() crea una etiqueta de cierre, asociada a la última etiqueta que se haya abierto. Por ello no es necesario incluir un valor Así se construye un String con el contenido del documento xml creado en el buffer Un writeEndDocument() cierra el documento XML que estamos creando writeStartDocument() inicia el documento, creando una etiqueta de cabecera xml, como <?xml version="1.0" ?> Así escribimos en un fichero XML físico el contenido del String recién construido ๏ Ejemplo que escribe en un XML un array de Alumno
  • 16. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 16JAXB en Java (I) ๏ Otro mecanismo para leer XML desde Java es usando JAXB. Está ya implementado en java desde la versión 6, con lo que no es necesario añadir ninguna biblioteca ๏ JAXB utiliza anotaciones para marcar, en una clase, qué información se va a convertir en etiquetas, qué en texto y qué en atributos ๏ Se basa en dos acciones, llamadas marshal y unmarshal, de la clase Marshaller (traducido, algo así como organizador): ‣ Marshalling – Convertir un objeto Java en un fichero XML . ‣ Unmarshalling – Convertir un fichero XML en un objeto Java ๏ El mecanismo es el siguiente: - Se crea un Contexto, que es un objeto de la clase JAXBContext. El contexto se crea con el método newInstance() indicándole a dicho contexto con qué clase va a tener que trabajar - Con dicho contexto, se crea un Marshaller, con el método createMarshaller() - Con el objeto marshaller ya se usan los métodos marshal() y unmurshal() para crear o leer de un fichero xml Crear Xml y leer con JAXB desde Java fichero.xml Clase javacontexto marshaller genera (marshal) lee crea Regenera (unmarshal)
  • 17. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 17JAXB en Java (II) ๏ Se crea un xml con una clase POJO simple @XmlRootElement @XmlType(propOrder={“nota","nombre"}) public class Alumno { private String nombre; private String id; private double nota; public Alumno() { } public Alumno(String nombre, String id, double nota) { this.nombre = nombre; this.id = id; this.nota = nota; } public String getNombre() { return nombre; } public String getId() { return id; } public double getNota() { return nota; } @XmlElement public void setNombre(String nombre) { this.nombre = nombre; } @XmlAttribute public void setId(String id) { this.id = id; } @XmlElement(name=“nota”) public void setNota(double nota) { this.nota = nota; } @Override public String toString() { return nombre+":"+" id="+id +":"+"nota="+nota+"}"; } } Clase Alumno, que será la que se use para crear un xml y luego leer de él. @XmlRootElement identifica a la clase que va a constituir el nodo raiz del XML Se puede indicar que en el xml tenga otro nombre, con el formato @XmlRootElement(name=“Estudiante") @XmlElement identifica a cada etiqueta interna dentro del nodo Alumno. No es obligatorio (ver más adelante “reglas de uso de anotaciones JAXB) @XmlAttribute identifica que el elemento será un atributo del nodo alumno Los getters son necesarios si existe un setter correspondiente que se ha marcado como elemento o atributo (ver más adelante “reglas de uso de anotaciones JAXB) @XmlType usa varios valores, con propOrder se indica el orden de los elementos dentro de nodo. Es opcional, si no se usa, se crean en el orden de la aparición en la clase Ejemplo primero, con una clase con atributos simples ( 1ª parte ) 1 (name=“nota”) identifica el nombre que se dará finalmente a cada etiqueta en el XML. Es opcional, si no se usa, se procesa el XML con el nombre del atributo
  • 18. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 18 public class JAXBPrueba { public static void main(String[] args) { Alumno a1 = new Alumno("Pepe", "E221", 5.1); try { // Crear el contexto, vale tanto para marshal como para unmarshal JAXBContext jaxbContext = JAXBContext.newInstance(Alumno.class); // -------------- CREAR FICHERO XML -------------------- // ------------------------------------------------------ // Crear marshaller Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // asi el xml tiene formato indentado y mas elegante jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); File file = new File("JAXBejemplo1.xml"); jaxbMarshaller.marshal(a1, file); //asi, lo que crea el marshaller va a fichero jaxbMarshaller.marshal(a1, System.out); //asi, lo que crea el marshaller va a pantalla // -------------- LEER FICHERO XML --------------------- // ------------------------------------------------------ // Crear unmarshaller Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); // la solucion del unmarshall es un object, se necesita casting para convertirlo en alumno Alumno al2 = (Alumno) jaxbUnmarshaller.unmarshal(file); System.out.println(“…………………………“); System.out.println("Alumno leido: "+al2); } catch (JAXBException e) { e.printStackTrace(); } } } consola <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <alumno id="E221"> <nota>5.1</nota> <nombre>Pepe</nombre> </alumno> ................................ Alumno leido: {nombre=Pepe: id=E221:nota=5.1} JAXB en Java (III) Ejemplo primero, con una clase con atributos simples ( y 2ª ) 2
  • 19. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 19 @XmlRootElement(name = "Automovil") @XmlType(propOrder = {"marca", "modelo", "propietario"}) public class Coche { private String marca; private String modelo; private int precio; private Persona propietario; public Coche() { } @XmlElement public void setPropietario(Persona propietario) { this.propietario = propietario; } @XmlElement public void setMarca(String marca) { this.marca = marca; } @XmlElement public void setModelo(String modelo) { this.modelo = modelo; } @XmlAttribute public void setPrecio(int precio) { this.precio = precio; } public Persona getPropietario() { return propietario; } public String getMarca() { return marca; } public int getPrecio() { return precio; } public String getModelo() { return modelo; } } JAXB en Java (IV) Ejemplo segundo, con un atributo que es un objeto Coche x2 = new Coche(); x2.setMarca("Kia"); x2.setModelo("Niro"); x2.setPrecio(19000); x2.setPropietario(new Persona("Eva", "55322242K")); JAXBContext contexto = JAXBContext.newInstance(Coche.class); // -------------- CREAR FICHERO XML -------------------- Marshaller miMarshaller = contexto.createMarshaller(); miMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); miMarshaller.marshal(x2, new File("JAXBejemplo2.xml")); miMarshaller.marshal(x2, System.out); // -------------- LEER FICHERO XML —————————— Unmarshaller miUnmarshaller = contexto.createUnmarshaller(); Coche nuevocoche = (Coche) miUnmarshaller.unmarshal( new File("JAXBejemplo2.xml")); System.out.println("................................"); System.out.println("Coche leido: " + nuevocoche.getMarca()); System.out.println("Propietario: " + nuevocoche.getPropietario().getNombre()); public class Persona { String nombre; String dni; public Persona() { } public Persona(String nombre, String dni) { this.nombre = nombre; this.dni = dni; } public String getNombre() { return nombre; } public String getDni() { return dni; } public void setNombre(String nombre) {this.nombre = nombre;} public void setDni(String dni) { this.dni = dni; } } ๏ En este caso la clase que se procesa tiene un atributo que es el objeto de otra clase ๏ Advertir que las anotaciones se hacen obligatorias solo en la clase principal. consola <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Automovil precio="19000"> <marca>Kia</marca> <modelo>Niro</modelo> <propietario> <dni>55322242K</dni> <nombre>Eva</nombre> </propietario> </Automovil> ................................ Coche leido: Kia Propietario: Eva
  • 20. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 20JAXB en Java (V) Ejemplo tercero, con un atributo que es una colección ( 1ª parte ) @XmlRootElement(name="GarageLopez") public class Garage implements Serializable { String nombre; List<Coche> listacoches ; List<String> condiciones ; public Garage() { } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public List<String> getCondiciones() { return condiciones; } public List<Coche> getListacoches() { return listacoches; } @XmlElementWrapper(name=“Condiciones generales”) @XmlElement(name = "Condiciones") public void setCondiciones(List<String> condiciones) { this.condiciones = condiciones; } @XmlElementWrapper(name="CochesOcupados") @XmlElement(name = "Coches") public void setListacoches(List<Coche> listacoches) { this.listacoches = listacoches; } } public class Coche { private String marca; private String modelo; private int precio; private Persona propietario; public Coche() { } public void setPropietario(Persona propietario) { this.propietario = propietario; } public void setMarca(String marca) { this.marca = marca; } public void setModelo(String modelo) { this.modelo = modelo; } public void setPrecio(int precio) { this.precio = precio;c } public Persona getPropietario() { return propietario; } public String getMarca() { return marca; } public String getModelo() { return modelo; } @XmlAttribute public int getPrecio() { return precio; } } public class Persona { String nombre; String dni; public Persona() { } public Persona(String nombre, String dni) { this.nombre = nombre; this.dni = dni; } public String getNombre() { return nombre; } public String getDni() { return dni; } public void setNombre(String nombre) {this.nombre = nombre;} public void setDni(String dni) { this.dni = dni; } } ๏ En este caso la clase que se procesa tiene dos atributos que son listas de objetos de otra clase ๏ Advertir que las anotaciones se hacen obligatorias solo en la clase principal, aunque se ha añadido solo una, para hacer que precio sea atributo de la etiqueta Coche @XmlElementWrapper indica que los las etiquetas del elemento que se procesa (normalmente una coleccion) se agrupan bajo una etiqueta global, suyo nombre es el que se añade 1
  • 21. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 21JAXB en Java (VI) Ejemplo tercero, con un atributo que es una colección ( y 2ª ) Coche x = new Coche(); x.setMarca("Seat"); x.setModelo("Ibiza"); x2.setPrecio(7000); x.setPropietario(new Persona("Paco", “66444373L")); Coche x2 = new Coche(); x2.setMarca("Kia"); x2.setModelo("Niro"); x2.setPrecio(19000); x2.setPropietario(new Persona("Eva", "55322242K")); ArrayList<Coche> coches = new ArrayList<>(); coches.add(x); coches.add(x2); ArrayList<String> condiciones = new ArrayList<>(); condiciones.add("salida emergencia"); condiciones.add("acceso con mando"); condiciones.add("area de lavado”); Garage garage = new Garage(); garage.setNombre("SuperGarage"); garage.setListacoches(coches); garage.setCondiciones(condiciones); JAXBContext contexto = JAXBContext.newInstance(Garage.class); Marshaller miMarshaller = contexto.createMarshaller(); miMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); miMarshaller.marshal(garage, new File("JAXBejemplo3.xml")); miMarshaller.marshal(garage, System.out); Unmarshaller miUnmarshaller = contexto.createUnmarshaller(); Garage nuevoGarage = (Garage) miUnmarshaller.unmarshal(new File(“JAXBejemplo3.xml")); System.out.println("................................"); System.out.println("Garage: " + nuevoGarage.getNombre()); System.out.println("Coche 1 : " + nuevoGarage.getListacoches().get(1).getMarca()); System.out.println("Propietario 1: " + nuevoGarage.getListacoches().get(1).getPropietario().getNombre()); consola <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <GarageLopez> <CondicionesGenerales> <Condiciones>salida emergencia</Condiciones> <Condiciones>acceso con mando</Condiciones> <Condiciones>area de lavado</Condiciones> </CondicionesGenerales> <CochesOcupados> <Coches precio="9000"> <marca>Seat</marca> <modelo>Ibiza</modelo> <propietario> <dni>66444373L</dni> <nombre>Paco</nombre> </propietario> </Coches> <Coches precio="19000"> <marca>Kia</marca> <modelo>Niro</modelo> <propietario> <dni>55322242K</dni> <nombre>Eva</nombre> </propietario> </Coches> </CochesOcupados> <nombre>SuperGarage</nombre> </GarageLopez> ................................ Garage: SuperGarage Coche 1 : Kia Propietario 1: Eva 2
  • 22. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 22JAXB en Java (VII) REGLAS DE USO DE LAS ANOTACIONES JAXB ๏ @XMLElement : 1. No es necesario en absoluto su uso (salvo que se desee añadir a la etiqueta XML un nombre distinto al del propio miembro de la clase). JAXB va a procesar por defecto y escribir en el XML: ‣ Cualquier atributo público (en tal caso, no deben tener @XMLElement sus getter ni setter, si existen estos métodos) ‣ Cualquier atributo privado, siempre que tenga su par de métodos públicos getter o setter. Además, deben existir los dos métodos para el atributo privado. 2. Si se usa (por ejemplo para añadir a la etiqueta XML un nombre distinto al del propio atributo de la clase): ‣ Se puede usar indistintamente en los getters o setters, pero no en los dos a la vez ‣ Se puede usar directamente en el atributo, pero este no puede tener sin getters ni setters (el atributo puede ser public o private, da igual) ‣ No se puede usar en un método que no sea getter o setter ‣ Si no se usan anotaciones, 3. Puede usarse simplemente la anotación @XMLElement o añadirle un valor para indicar el nombre que ha de tomar la etiqueta en el XML : @XMLElement(name=“nombrexml”) ๏ @XMLElementWrapper : 4. No es obligatorio su uso con colecciones . Si no se usa, la colección se creará elemento a elemento en el XML. Si se usa, entonces, todos los elementos de la colección tendrán un padre común, precisamente el indicado por el atributo- colección donde se aplica @XMLElementWrapper , salvo que se indique expresamente un nuevo nombre con @XMLElementWrapper(name=“nombreagrupadorxml”) ๏ @XmlAccessorType(XmlAccessType.NONE) : 5. Obliga al uso de anotaciones, no permitiendo que se generen por defecto según de indica la regal 1 indicada anteriormente. El valor contrario (el que se aplica por defecto si no se pone nada) es @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
  • 23. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 23JAXB en Java (VIII) JAXB y clases de java.timeTemas avanzados ๏ JAXB no funciona correctamente si se usan clases que se han incorporado a la suite de JAVA con posterioridad a la implantación de JAXB. Uno de los ejemplos es con el paquete java.time, clases con las que JAXB no tiene solución para serializar y deserializar (convertir a bytes y recuperar de bytes) clases como LocalDate, LocalTime, LocalDateTime, y ZonedDateTime. Vamos, que con esas clases, JAXB no funciona directamente. ๏ Para solucionarlo hay que crearse adaptadores personalizados que procesen el marshall y unmarshall de dichos datos. Este es un ejemplo de un adaptador muy sencillo, pero que nos saca del apuro: public class LocalDateAdapter extends XmlAdapter<String, LocalDate> { public LocalDate unmarshal(String v) throws Exception { return LocalDate.parse(v); } public String marshal(LocalDate v) throws Exception { return v.toString(); } } @XmlJavaTypeAdapter(value = LocalDateAdapter.class) public LocalDate getFecha() { return fecha; } ๏ Posteriormente, no se pueden usar anotaciones directas como las ya vistas de JAXB en los atributos que sean LocalDate o similares, sino hemos de usar la anotación genérica @XmlJavaTypeAdapter indicando que se aplica nuestro adaptador recién creado, como en este ejemplo;
  • 24. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 24 ๏ Para crear contenido JSON vamos a usar una librería llamada GSON (https://github.com/google/gson) ๏ Descargar de dicha página el .jar con la librería a usar, crear un proyecto e instalar la librería en el mismo, bien por medio de las preferencias del proyecto, o si se usa por ejemplo Gradle (como lo hace Android Studio) se añade la dependencia directamente, sin tener que descargar ni instalar nada: ๏ Este es un simple ejemplo del uso de GSON, dentro de una clase, que crea el texto de un JSON desde un objeto, y desde el propio texto, lo vuelve a montar en un objeto propio: Crear texto JSON de un objeto Java dependencies { implementation 'com.google.code.gson:gson:2.8.5' } class Libro { String autor; String titulo; double precio; public String convertirAJson() { Gson unGson = new Gson(); String cadenaEnFormatoGSON = unGson.toJson(this); return cadenaEnFormatoGSON; } public Libro recuperarDeJson(String cadenaEnFormatoGSON) { Gson unGson = new Gson(); Libro libroRecuperado = unGson.fromJson(cadenaEnFormatoGSON, Libro.class); return libroRecuperado; } public Libro(String autor, String titulo, double precio) { this.autor = autor; this.titulo = titulo; this.precio = precio; } } Si se desea una estructura mas compleja, como un array o un ArrayList, basta con meter el array o ArrayList como atributo de la clase, crear el objeto del mismo modo, y recuperarlo también igualmente (ejemplo en paginas siguientes) public class PruebaJSON { public static void main(String[] args) { Libro unlibro = new Libro("Cervantes", "EL Quijote", 33.50); String objetoEnJSon = unlibro.convertirAJson(); System.out.println(objetoEnJSon); Libro libroRecogidoDeJson = new Libro().recuperarDeJson(objetoEnJSon); System.out.println(libroRecogidoDeJson.autor); } } consola {"autor":"Cervantes","titulo":"EL Quijote","precio":33.5} Cervantes JSON en Java (I)
  • 25. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF 25 ๏ En este caso, la clase contiene un array, pero la creación del JSON y recuperación del mismo se hace… exactamente igual que antes Crear texto JSON de una clase que contiene una colección (arrays o listas) class Libreria { String nombre; Libro[] libros; public Libreria(String nombre, Libro[] libros) { this.nombre=nombre; this.libros=libros; } public String convertirAJson() { Gson unGson = new Gson(); String cadenaEnFormatoGSON = unGson.toJson(this); return cadenaEnFormatoGSON; } public Libreria recuperarDeJson(String cadenaEnFormatoGSON) { Gson unGson = new Gson(); Libreria libreriaRecuperada = unGson.fromJson(cadenaEnFormatoGSON, Libreria.class); return libreriaRecuperada; } } public class PruebaJSON { public static void main(String[] args) { Libro[] libros = new Libro[3]; libros[0] = new Libro("Cervantes", "El Quijote", 33.50); libros[1] = new Libro("C. Jose Cela", "La Colmena", 11.80); libros[2] = new Libro("C. Jose Cela", "San Camilo 1936", 22.00); Libreria libreria = new Libreria("ViejosLibros", libros); String libreriaEnJson = libreria.convertirAJson(); System.out.println(libreriaEnJson); Libreria libreriaNueva = libreria.recuperarDeJson(libreriaEnJson); System.out.println(libreriaNueva.nombre); System.out.println(libreriaNueva.libros[1].titulo); } } consola { "nombre": "ViejosLibros", "libros": [{ "autor": "Cervantes", "titulo": "El Quijote", "precio": 33.5 }, { "autor": "C. Jose Cela", "titulo": "La Colmena", "precio": 11.8 }, { "autor": "C. Jose Cela", "titulo": "San Camilo 1936", "precio": 22.0 }] } ViejosLibros La Colmena JSON en Java (II)
  • 26. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF JSON en Java (III) 26 ๏ Aunque también se puede convertir a JSON una colección (array o arraylist) directamente, sin que la colección forme parte de una clase. a) Con un array, igual que con una clase, indicando al fromJSON que el tipo de dato que se deserializa es un Libro[].class Crear texto JSON directamente de una colección (arrays o listas) Libro[] libros = new Libro[3]; libros[0] = new Libro("Cervantes", "El Quijote", 33.50); libros[1] = new Libro("C. Jose Cela", "La Colmena", 11.80); libros[2] = new Libro("C. Jose Cela", "San Camilo 1936", 22.00); Gson unGson = new Gson(); String arrayEnFormatoGSON = unGson.toJson(libros); System.out.println(arrayEnFormatoGSON); Libro[] arrayRecuperado = unGson.fromJson(arrayEnFormatoGSON, Libro[].class); System.out.println(libros[1].titulo); ArrayList<Libro> libros = new ArrayList<Libro>(); libros.add( new Libro("Cervantes", "El Quijote", 33.50)); libros.add( new Libro("C. Jose Cela", "La Colmena", 11.80)); libros.add( new Libro("C. Jose Cela", "San Camilo 1936", 22.00)); Gson unGson = new Gson(); String arrayListEnFormatoGSON = unGson.toJson(libros); System.out.println(arrayListEnFormatoGSON); // No se puede usar en fromJSON un ArrayList como tipo de dato // Hay que sacar el "tipo de dato" del ArrayList con la clase TypeToken de GSON // y la clase Type de Java Type typeDeArrayListDeLibro = new TypeToken<ArrayList<Libro>>(){}.getType(); ArrayList<Libro> arrayListRecuperado = unGson.fromJson(arrayListEnFormatoGSON, typeDeArrayListDeLibro); System.out.println(arrayListRecuperado.get(1).titulo); consola [{ "autor": "Cervantes", "titulo": "El Quijote", "precio": 33.5 }, { "autor": "C. Jose Cela", "titulo": "La Colmena", "precio": 11.8 }, { "autor": "C. Jose Cela", "titulo": "San Camilo 1936", "precio": 22.0 }] La Colmena b) Con un ArrayList, convirtiendo a JSON igual que con una clase, pero al deserializar con fromJSON hay un problema, no se puede usar un ArrayList como tipo de dato, así que hay que sacar el "tipo de dato" del ArrayList con la clase TypeToken de GSON y la clase Type de Java Los import de estas dos clases son: import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type;
  • 27. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF ๏ Para crear PF vamos a usar una utilidad de mercado llamada iText ๏ Antes de empezar con el código, hemos de agregar las librerías necesarias. ๏ Vamos a aprovechar y a explicar como crear un proyecto Maven, para aprovechar sus dependencias y ver otro modo de añadir librerías a un proyecto: ๏ Elegir New Project - Maven - Next ๏ En la pantalla siguiente, escribir: ✦ Groupid : com.itextpdf (es donde luego vamos a montar las dependencias externas) ✦ ArtifactId: el nombre de nuestro Artefacto. Puede ser el mismo que el proyecto ✦ Version: dejar la que sale por defecto o cambiar si se desea ✦ Elegir Next Crear PDF Añadir librerias en un proyecto MAVEN (con IDE IntelliJ) 27 Crear un PDF desde un programa JAVA
  • 28. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF • En la pantalla siguiente, escribir: ✦ ProjectName : el nombre de nuestro proyecto, con dominio si se desea (puede se igual que el Artefacto) ✦ ProjectLocation: ubicación del proyecto ✦ Finish Puede aparecer ahora un mensaje como : Activar los cambios como se desee, de las dos opciones ofrecidas Crear PDF 28
  • 29. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.itextpdf</groupId> // Estas tres lineas son la referencia, no de una dependencia, sino del <artifactId>jyocPdfJava</artifactId> // propio programa principal <version>1.0-SNAPSHOT</version> // Para añadir dependencias, consultar al proveedor para informarse de los nombres y versiones correctos de las librerias a añadir // (no suelen coincidir con los nombres de los ficheros JAR) <dependencies> <dependency> // PRIMERA DEPENDENCIA <groupId>com.itextpdf</groupId> // groupId : debe coincidir con el identificado al crear el proyecto <artifactId>kernel</artifactId> // artifactId : es aqui el NOMBRE de la libreria que queremos importar <version>7.0.2</version> // version : es la version que vamos a utilizar </dependency> <dependency> // RESTO DE DEPENDENCIAS . Igual que la anterior <groupId>com.itextpdf</groupId> <artifactId>io</artifactId> <version>7.0.2</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>layout</artifactId> <version>7.0.2</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>forms</artifactId> <version>7.0.2</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>pdfa</artifactId> <version>7.0.2</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>pdftest</artifactId> <version>7.0.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.18</version> </dependency> </dependencies> </project> Crear PDF 29 • Aparece también una ventana con el fichero de configuración de dependencias. Aquí hemos de incluir la información de las librerías que deseamos configurar para el proyecto, de modo que se actualicen automáticamente. Aquí se muestra el contenido del fichero con las dependencias ya añadidas. El fichero inicialmente tiene un contenido que se marca en blanco. En la representación se explica cómo se configura cada librería añadida como dependencia.
  • 30. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF (continua… ) Crear PDF 30 import com.itextpdf.io.font.FontConstants; import com.itextpdf.io.image.ImageDataFactory; import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.*; import java.io.IOException; public class CrearPdfEnJava { public static final String FICHERODESTINO = "MiPrimerPdf.pdf"; public final String IMAG1 = "Logo_JYOC_crema_pq.png"; public static final String FICHCSV = "capitales.csv"; public static void main(String args[]) throws IOException { // Si el nombre del fichero incluye path, añadir la linea siguiente // para asegurar que se crean los directorios intermedios para crear el fichero // new File(FICHERODESTINO).getParentFile().mkdirs(); new CrearPdfEnJava().crearPdf(FICHERODESTINO); } public void crearPdf(String dest) throws IOException { // Inicializar PDFwriter PdfWriter writer = new PdfWriter(dest); // Inicializar PDFdocument PdfDocument pdf = new PdfDocument(writer); // Inicializar document Document document = new Document(pdf); // aplicamos margenes al document document.setMargins(20, 20, 20, 20); // AÑADIR TEXTOS ********************************************************* // Añadir un par de lineas (párrafos) document.add(new Paragraph("Una primera linea en el documento")); document.add(new Paragraph("Una segundfa linea que quede debajo”)); // Crear una PdfFont PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN); // Aplicar una fuente a un Paragraph document.add(new Paragraph("Ejemplo de lista con viñetas:").setFont(font)); (continua) ➡
  • 31. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF // AÑADIR LISTAS **************************************************** // Crear una List, un grupo de lineas con un font, tamaño // y caracteristicas compartidas, incluidas viñetas List list = new List() .setSymbolIndent(12) .setListSymbol("u2022") .setFont(font); // Añadir elementos (ListItem) a la lista list.add(new ListItem("Con cien cañones por banda")) .add(new ListItem("viento en popa a toda vela")) .add(new ListItem("no corta el mar sino vuela")) .add(new ListItem("un velero bergantín")); // Agregar la lista al document document.add(list); // AÑADIR UNA IMAGEN ******************************** // Crear una imagen y añadirla a un parrafo Image im1 = new Image(ImageDataFactory.create(IMAG1)); Paragraph p = new Paragraph("Una imagen...”) .add(im1) .add(" ...encuadrada entre dos lineas."); // Agregar el parrafo con imagen al document document.add(p); PDF Resultante del ejercicio: Crear PDF 31
  • 32. TemariodecursoJavaSE©IñakiMartín
 15.- Ficheros XML, JSON, PDF Crear PDF 32 // AÑADIR UNA TABLA ********************************************************* PdfFont fontNormal = PdfFontFactory.createFont(FontConstants.HELVETICA); PdfFont fontbold = PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD); // Crear el elemento table, en el constructor recibe un array de float con // tantos elementos como columnas de la tabla // El valor indica la proporcionalidad del tamaño de las columnas Table tabla = new Table(new float[]{3, 1, 1, 1}); tabla.setWidthPercent(100); String[][] textos = {{"Capital", "Provincia", "Población", "Idioma"}, {"Vitoria", "Alava", "244600", "Euskera"}, {"Bilbao", "Vizcaya", "345000", "Euskera"}, {"Donostia", "Guipuzcoa", "186000", "Euskera"}, {"Pamplona", "Navarra", "201000", "Euskera"}, {"Logroño", "La Rioja", "150000", "Castellano"}, {"Oviedo", "Asturias", "220000", "Castellano (Bable)"}}; procesarTabla(tabla, textos[0], fontbold, true); for (int i = 1; i < textos.length; i++) { procesarTabla(tabla, textos[i], fontNormal, true); } document.add(tabla); // Cerrar document document.close(); } public void procesarTabla(Table pTabla, String[] pLinea, PdfFont pFont, boolean pEsCabecera) { for (int j = 0; j < pLinea.length; j++) { // Se crea la celda a añadir Cell celda = new Cell(); celda.add(new Paragraph(pLinea[j]).setFont(pFont)); // Añadimos la celda a la tabla, aunque se usan metodos diferentes si la celda es // una fila de cabecera o no. if (pEsCabecera) { pTabla.addHeaderCell(celda); } else { pTabla.addCell(celda); } } }