Java y XML

Ya hemos visto cómo Java tiene su lugar en el mundo de las aplicaciones web (applets, servlets, JSP).

Curso de Java

Acabamos de ver cómo es el lenguaje XML. Entre las aplicaciones de XML en el mundo web están: Mantenimiento de bases de datos en documentos de texto. Intercambio de información entre sistemas (EDI). Java también tendrá que entenderse con esas aplicaciones de XML. Tendremos que saber hacer muchas cosas con documentos XML: Generación de documentos XML. Consumo de documentos XML. Transferencia de información entre dos bases de datos. Etcétera.

Java y XML
El lenguaje Java — Tema 13 — Java y XML

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 1

Uso de Java en documentos XML

fecha.jsp

De la base de datos al documento XML
<%@ page contentType='text/xml' %> <%@ page import="java.sql.*" %> <?xml version="1.0" encoding="UTF-7"?> <bd> <% try { String urlBD = "jdbc:odbc:JDBC_ALUMNOS"; Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection conexion = DriverManager.getConnection(urlBD); Statement select = conexion.createStatement(); String sql = "SELECT * FROM Tabla1 ORDER BY NOMBRE"; ResultSet resultadoSelect = select.executeQuery(sql); while(resultadoSelect.next()) { %> <alumno> <nombre><%= resultadoSelect.getString("Nombre") %></nombre> <edad><%= resultadoSelect.getString("Edad") %></edad> <dir><%= resultadoSelect.getString("Direccion") %></dir> </alumno>
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 3

Java puede participar en la construcción de documentos XML. Normalmente mediante JSP (los guiones de servidor también se pueden colocar en documentos XML): <%@ page contentType='text/xml' %> <?xml version="1.0" encoding="UTF-7"?> <documento> <fecha><%= new java.util.Date() %></fecha> </documento>

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 2

De la base de datos al documento XML
<% }; resultadoSelect.close(); select.close(); conexion.close(); } catch(SQLException ex) { out.println("Error: SQLException."); } catch( Exception ex) { out.println("Error inesperado."); } %> </bd>

De la base de datos al documento XML

bd.jsp
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 4 Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 5

Análisis de documentos XML
Análisis de un documento XML: extracción de su información. Una vez que disponemos de la información del documento XML podemos hacer con ella lo que necesitemos. Dos tecnologías Java para el análisis de documentos XML: SAX: Simple API for XML. DOM: Document Object Model. SAX proporciona un framework para realizar tareas a medida que se analiza el documento XML y se van encontrando sus distintos componentes (elementos, atributos, valores). DOM se apoya en SAX para construir un árbol que representa los componentes del documento XML y sus relaciones de inclusión.

SAX: Simple API for XML
Permite indicar el código a ejecutar cada vez que se encuentra un elemento mientras se analiza el documento XML.

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 6

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 7

SAX: Simple API for XML
DefaultHandler implementa las cuatro interfaces ContentHandler ErrorHandler DTDHandler EntityResolver con métodos vacíos, de forma que podamos redefinir sólo aquellos que nos interesen en cada aplicación particular. org.xml.sax.helpers SAXParserFactory crea un ejemplar de analizador (SAXParser). SAXParser analiza el documento XML apoyándose en los métodos definidos en el DefaultHandler. javax.xml.parsers

Análisis de documentos XML con SAX
import import import import import import import java.io.*; org.xml.sax.*; org.xml.sax.helpers.DefaultHandler; javax.xml.parsers.SAXParserFactory; javax.xml.parsers.ParserConfigurationException; javax.xml.parsers.SAXParser; java.util.Vector;

public class Analiza extends DefaultHandler { public Vector analiza(String archivo) { DefaultHandler handler = new Analiza(); SAXParserFactory fact = SAXParserFactory.newInstance(); try { SAXParser parser = fact.newSAXParser(); parser.parse(new File(archivo), handler); } catch (Throwable t) { t.printStackTrace(); } }
Luis Hernández Yáñez

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 8

Curso de Java

Tema 13 – Java y XML - 9

Análisis de documentos XML con SAX
public void startElement(String uri, String nombre, String cualificado, Attributes atr) throws SAXException { // Comienzo de un elemento XML } public void endElement(String uri, String nombre, String cualificado) throws SAXException { // Final de un elemento XML } public void characters(char[] buf, int ini, int lon) throws SAXException { // Secuencia de caracteres } }

Análisis de documentos XML con SAX
<TIENDA> <EQUIPO TIPO="Sobremesa" COLOR="Negro"> <NOMBRE>FX300 UM</NOMBRE> <PRECIO> <PESETAS>166386</PESETAS> <EUROS>1000</EUROS> </PRECIO> Comienzo de elemento Secuencia de caracteres Final de elemento

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 10

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 11

Análisis de documentos XML con SAX
Guardaremos la información de cada elemento en un objeto. Debemos conocer la clase Attributes, que representa los atributos del elemento XML. getLength(): número de atributos. getQName(i): nombre del atributo i-ésimo. getValue(i): valor del atributo i-ésimo. Clase Elemento para guardar la información: public class Elemento { String nombre; String valor = null; String atributos; ... }
Curso de Java

Análisis de documentos XML con SAX

Elemento.java

Para simplificar, guardaremos los atributos y sus valores en una cadena de texto.
Tema 13 – Java y XML - 12

import org.xml.sax.*; public class Elemento { String nombre; String valor = null; String atributos; public Elemento(String nombre, Attributes atr) { this.nombre = nombre; atributos = new String(); for(int i = 0; i < atr.getLength(); i++) { atributos += atr.getQName(i) + "='" + atr.getValue(i) + "' "; } } public void ponValor(String valor) { this.valor = valor; } public String dameNombre() { return nombre; } public String dameValor() { return valor; } public String dameAtributos() { return atributos; } }
Luis Hernández Yáñez

Luis Hernández Yáñez

Curso de Java

Tema 13 – Java y XML - 13

Análisis de documentos XML con SAX
import import import import import import import java.io.*; org.xml.sax.*; org.xml.sax.helpers.DefaultHandler; javax.xml.parsers.SAXParserFactory; javax.xml.parsers.ParserConfigurationException; javax.xml.parsers.SAXParser; java.util.Vector;

Análisis de documentos XML con SAX
public void startElement(String uri, String nombre, String cualificado, Attributes atr) throws SAXException { actual = new Elemento(cualificado, atr); lista.addElement(actual); texto = new String(); } public void endElement(String uri, String nombre, String cualificado) throws SAXException { if(actual != null && texto != null) actual.ponValor(texto.trim()); actual = null; } public void characters(char[] buf, int ini, int lon) throws SAXException { if(actual != null && texto != null) { String valor = new String(buf, ini, lon); texto += valor; } } }
Luis Hernández Yáñez

public class Analiza extends DefaultHandler { private static Vector lista = new Vector(); private Elemento actual = null; private String texto; public Vector analiza(String archivo) { DefaultHandler handler = new Analiza(); SAXParserFactory fact = SAXParserFactory.newInstance(); try { SAXParser parser = fact.newSAXParser(); parser.parse(new File(archivo), handler); } catch (Throwable t) { t.printStackTrace(); } return lista; }
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 14

Analiza.java
Tema 13 – Java y XML - 15

Curso de Java

Análisis de documentos XML con SAX
import java.io.*; import java.util.Vector;

Prueba.java

Análisis de documentos XML con SAX
Elementos encontrados: 19 Elemento: TIENDA Atributos: Valor: null Elemento: EQUIPO Atributos: TIPO='Sobremesa' COLOR='Negro' Valor: null Elemento: NOMBRE Atributos: Valor: FX300 UM Elemento: PRECIO Atributos: Valor: null Elemento: PESETAS Atributos: Valor: 166386 Elemento: EUROS Atributos: Valor: 1000 Elemento: CARACTERISTICAS Atributos: CPU='Pentium III' VELOCIDAD='800' ...
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 17

public class Prueba { public static void main(String argv[]) { Vector v; Elemento el; Analiza an = new Analiza(); v = an.analiza("Equipos.xml"); System.out.println("Elementos encontrados: " + v.size()); for(int i = 0; i < v.size(); i++) { el = (Elemento) v.get(i); System.out.println("Elemento: " + el.dameNombre()); System.out.println("Atributos: " + el.dameAtributos()); System.out.println("Valor: " + el.dameValor()); } } }

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 16

Análisis de documentos XML con SAX
Ejercicios Crea una página JSP analiza.jsp que muestre en forma de tabla la información de los elementos XML encontrados en el documento Equipos.xml. Nota: Para poder utilizar las clases Analiza y Elemento en la página JSP es necesario que esas clases se encuentren en: C:\Blazix\classes

DOM: Document Object Model
Un framework que permite obtener un árbol cuyos nodos representan el contenido de un documento XML.

Crea un programa Eco.java que replique en System.out el documento XML Equipos.xml después de haberlo analizado con SAX.

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 18

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 19

DOM: Document Object Model
Document es el árbol que representa el contenido del documento. Se obtiene con un analizador. org.w3c.dom.Document DocumentBuilderFactory crea un ejemplar de analizador (DocumentBuilder). javax.xml.parsers.DocumentBuilderFactory DocumentBuilder analiza el documento XML y genera el Document. javax.xml.parsers.DocumentBuilder

Análisis de un documento XML con DOM
import import import import import import import import import javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; javax.xml.parsers.FactoryConfigurationError; javax.xml.parsers.ParserConfigurationException; org.xml.sax.SAXException; org.xml.sax.SAXParseException; java.io.IOException; org.w3c.dom.Document; org.w3c.dom.DOMException;

public class DOM1 { static Document document; public static void main(String argv[]) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse("Equipos.xml"); } catch ...
Luis Hernández Yáñez

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 20

Curso de Java

Tema 13 – Java y XML - 21

El documento XML
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- File name: Equipos.xml --> <?xml-stylesheet type="text/xsl" href="Equipos2.xsl"?> <TIENDA> <EQUIPO TIPO="Sobremesa" COLOR="Negro"> <NOMBRE>FX300 UM</NOMBRE> <PRECIO> <PESETAS>166386</PESETAS> <EUROS>1000</EUROS> </PRECIO> <CARACTERISTICAS CPU="Pentium III" VELOCIDAD="800"> <MEMORIA>128</MEMORIA> <DISCO>15</DISCO> </CARACTERISTICAS> <OPCIONES>Multimedia, Grabadora de CD</OPCIONES> </EQUIPO> <EQUIPO TIPO="Portátil" COLOR="Plateado"> <NOMBRE>LT150 HX</NOMBRE> ...
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 22

El árbol del documento (Document)
Document #document Comment #comment File name: Equipos.xml Text #text Element EQUIPO

Node

Tipo Nombre Valor

ProcInstr xml-stylesheet type="text/xsl" href="Equipos2.xsl" Text #text Element EQUIPO Text #text

Element TIENDA

...
Text #text Element NOMBRE Text #text FX300 UM Attr COLOR Negro Text #text Text #text Element PRECIO Element PESETAS Text #text 166386
Luis Hernández Yáñez

...

Text #text Text #text Element EUROS Text #text 1000 Text #text

Lista de atributos Attr TIPO Sobremesa
Curso de Java

Tema 13 – Java y XML - 23

org.w3c.dom.Node
Document es subclase de Node. Algunos métodos de la clase Node: String getNodeName() String getNodeType() String getNodeValue() boolean hasAttributes() NamedNodeMap getAttributes() boolean hasChildNodes() NodeList getChilNodes() Nombre Tipo Valor ¿Tiene atributos? Lista de atributos ¿Tiene hijos? Lista de hijos

org.w3c.dom.Node
Tipos de nodos

Otros métodos permiten modificar o ampliar la estructura del árbol.

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 24

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 25

org.w3c.dom.NodeList
Para la lista de nodos hijos. Métodos de la clase NodeList: int getLength() Node item(int) Número de nodos en la lista Nodo en la posición indicada

Recorrido del árbol DOM
import import import import import import import import import import import javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; javax.xml.parsers.FactoryConfigurationError; javax.xml.parsers.ParserConfigurationException; org.xml.sax.SAXException; org.xml.sax.SAXParseException; java.io.IOException; org.w3c.dom.Document; org.w3c.dom.DOMException; org.w3c.dom.Node; org.w3c.dom.NodeList;

NodeList hijos = nodo.getChildNodes(); for(int n = 0; n < hijos.getLength(); n++) { Node hijo = hijos.item(n); ... }

public class DOM1 { static Document document; public static void main(String argv[]) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 26

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 27

Recorrido del árbol DOM
try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse("Equipos.xml"); procesa(document); } catch (SAXParseException spe) { // Error generated by the parser System.out.println("** Parsing error**"); } catch (SAXException sxe) { // Error generated during parsing Exception x = sxe; if(sxe.getException() != null) x = sxe.getException(); x.printStackTrace(); } catch (ParserConfigurationException pce) { // Parser with specified options can't be built pce.printStackTrace(); } catch (IOException ioe) { // I/O error ioe.printStackTrace(); } } // main()
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 28

Recorrido del árbol DOM
// An array of names for DOM node-types static final String[] typeName = { "none", "Element", "Attr", "Text", "CDATA", "EntityRef", "Entity", "ProcInstr", "Comment", "Document", "DocType", "DocFragment", "Notation", };

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 29

Recorrido del árbol DOM
public static void procesa(Node nodo) { String s = typeName[nodo.getNodeType()]; s += ": " + nodo.getNodeName(); if(nodo.getNodeValue() != null) { s += ": " + nodo.getNodeValue().trim(); } System.out.println(s); NodeList hijos = nodo.getChildNodes(); for(int n = 0; n < hijos.getLength(); n++) { Node hijo = hijos.item(n); procesa(hijo); } } } // Clase DOM1

Recorrido del árbol DOM
Document: #document Comment: #comment: File name: Equipos.xml ProcInstr: xml-stylesheet: type="text/xsl" href="Equipos2.xsl" Element: TIENDA Text: #text: Element: EQUIPO Text: #text: Element: NOMBRE Text: #text: FX300 UM Text: #text: Tipo: Nombre: Valor Element: PRECIO Text: #text: Element: PESETAS Text: #text: 166386 Si hay valor asociado Text: #text: Element: EUROS Text: #text: 1000 Text: #text: Text: #text: Element: CARACTERISTICAS Text: #text: Element: MEMORIA Text: #text: 128 Text: #text: Element: DISCO Text: #text: 15 ...
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 31

DOM1.java
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 30

org.w3c.dom.NamedNodeMap
Para las listas de atributos, que también son nodos. Algunos métodos de la clase NamedNodeMap: int getLength() Node item(int) Número de nodos en la lista Nodo en la posición indicada

El documento XML a partir del árbol DOM
Incluyendo atributos pero obviando el prólogo. Hay que importar NamedNodeMap: import org.w3c.dom.NamedNodeMap;
public class DOM2 { static Document document; public static void main(String argv[]) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse("Equipos.xml"); procesa(document); System.out.println(); } catch (SAXParseException spe) { ...

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 32

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 33

El documento XML a partir del árbol DOM
... } // main() public static void procesa(Node nodo) { String nombre = ""; if(nodo.getNodeType() == 1) { // Un elemento nombre = nodo.getNodeName(); System.out.print("<" + nombre); if(nodo.hasAttributes()) { NamedNodeMap atributos = nodo.getAttributes(); for(int a = 0; a < atributos.getLength(); a++) { Node atr = atributos.item(a); System.out.print(" " + atr.getNodeName() + "='" + atr.getNodeValue() + "'"); } } System.out.print(">"); } else if(nodo.getNodeType() == 3) { // Texto System.out.print(nodo.getNodeValue()); }
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 34

El documento XML a partir del árbol DOM
NodeList hijos = nodo.getChildNodes(); for(int n = 0; n < hijos.getLength(); n++) { Node hijo = hijos.item(n); procesa(hijo); } if(nodo.getNodeType() == 1) { // Un elemento System.out.print("</" + nombre + ">"); } } } // Clase DOM2

DOM2.java
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 35

El documento XML a partir del árbol DOM
<TIENDA> <EQUIPO TIPO='Sobremesa' COLOR='Negro'> <NOMBRE>FX300 UM</NOMBRE> <PRECIO> <PESETAS>166386</PESETAS> <EUROS>1000</EUROS> </PRECIO> <CARACTERISTICAS CPU='Pentium III' VELOCIDAD='800'> <MEMORIA>128</MEMORIA> <DISCO>15</DISCO> </CARACTERISTICAS> <OPCIONES>Multimedia, Grabadora de CD</OPCIONES> </EQUIPO> <EQUIPO TIPO='Portßtil' COLOR='Plateado'> <NOMBRE>LT150 HX</NOMBRE> <PRECIO> <PESETAS>256800</PESETAS> <EUROS>1346.28</EUROS> </PRECIO> <CARACTERISTICAS CPU='Pentium III' VELOCIDAD='700'> <MEMORIA>128</MEMORIA> <DISCO>10</DISCO> </CARACTERISTICAS> <OPCIONES>Multimedia, CD 50X</OPCIONES> </EQUIPO> </TIENDA>
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 36

Ejercicio
Crear un programa DOM3 que a partir del árbol DOM del documento Equipos.xml construya una lista (vector) de los equipos descritos en ese documento XML. Luego mostrará la información de la lista. La información que contiene el documento sobre cada equipo (elementos terminales y atributos) es: Nombre Tipo Color Pesetas Euros CPU Velocidad Memoria Disco Opciones

Todos los datos en forma de cadenas de caracteres

Crear una clase auxiliar Equipo que reúna la información del equipo.
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 37

Intercambio electrónico de datos (EDI)
Al principio de este tema vimos cómo convertir a XML el contenido de una tabla de una base de datos. El intercambio electrónico de datos (EDI) puede realizarse por medio de documentos XML:

Del documento XML a la base de datos
... import java.sql.*; public class DOMBD { static Document document; static Vector lista = new Vector(); static Equipo eq; public static void main(String argv[]) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse("Equipos.xml"); DOMBD dom = new DOMBD(); } catch (SAXParseException spe) { ...

BD origen

Java

Equipos.xml

Java

BD destino

Lo que nos queda por hacer es volcar el documento XML en una tabla de una base de datos.
Luis Hernández Yáñez

Curso de Java

Tema 13 – Java y XML - 38

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 39

Del documento XML a la base de datos
} // main() public DOMBD() { Node nodo = document; procesa(nodo); try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection conexion = DriverManager.getConnection("jdbc:odbc:JDBC_EQUIPOS"); Statement stmt = conexion.createStatement(); for(int i = 0; i < lista.size(); i++) { eq = (Equipo) lista.get(i); String sql = "INSERT INTO Equipos (Nombre, Tipo, Color, PrecioPts"; sql += ", PrecioEur, CPU, Velocidad, Memoria, Disco, Opciones) VALUES ("; sql += "'" + eq.nombre + "', '" + eq.tipo + "', '" + eq.color; sql += "', " + eq.pesetas + ", " + eq.euros + ", '" + eq.cpu; sql += "', " + eq.velocidad + ", " + eq.memoria + ", " + eq.disco; sql += ", '" + eq.opciones + "')"; stmt.executeUpdate(sql); } conexion.close(); } catch(Exception e) { e.printStackTrace(); } } // DOMBD()
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 40

Del documento XML a la base de datos
public String valor(Node nodo) { NodeList hijos = nodo.getChildNodes(); String v = new String(); for(int n = 0; n < hijos.getLength(); n++) { Node hijo = hijos.item(n); if(hijo.getNodeType() == 3) v += hijo.getNodeValue(); } return v; } public void procesa(Node nodo) { String nombre = ""; if(nodo.getNodeType() == 1) { // Un elemento if(nodo.getNodeName() == "EQUIPO") eq = new Equipo(); else if(nodo.getNodeName()=="NOMBRE") eq.nombre=valor(nodo); else if(nodo.getNodeName()=="PESETAS") eq.pesetas=valor(nodo); else if(nodo.getNodeName()=="EUROS") eq.euros=valor(nodo); else if(nodo.getNodeName()=="MEMORIA") eq.memoria=valor(nodo); else if(nodo.getNodeName()=="DISCO") eq.disco=valor(nodo); else if(nodo.getNodeName()=="OPCIONES") eq.opciones=valor(nodo);

Curso de Java

Luis Hernández Yáñez

Tema 13 – Java y XML - 41

Del documento XML a la base de datos

DOMBD.java

Del documento XML a la base de datos

if(nodo.hasAttributes()) { NamedNodeMap atributos = nodo.getAttributes(); for(int a = 0; a < atributos.getLength(); a++) { Node atr = atributos.item(a); if(atr.getNodeName() == "TIPO") eq.tipo = atr.getNodeValue(); if(atr.getNodeName() == "COLOR") eq.color = atr.getNodeValue(); if(atr.getNodeName() == "CPU") eq.cpu = atr.getNodeValue(); if(atr.getNodeName() == "VELOCIDAD") eq.velocidad = atr.getNodeValue(); } } } NodeList hijos = nodo.getChildNodes(); for(int n = 0; n < hijos.getLength(); n++) { Node hijo = hijos.item(n); procesa(hijo); } if(nodo.getNodeType() == 1) { // Un elemento if(nodo.getNodeName() == "EQUIPO") lista.addElement(eq); } } // procesa() public class Equipo { public String nombre, tipo, color, pesetas, euros, cpu, velocidad, memoria, disco, opciones; } } // Clase DOMBD
Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 42 Curso de Java Luis Hernández Yáñez Tema 13 – Java y XML - 43