Analizar XML con Java

Aunque el formato de datos XML alardea de características como: extensibilidad, legibilidad, jerarquización, estandarización y capacidad de adaptación a multitud de formatos. A la hora de analizarlo y extraer información de él es, computacionalmente, un formato que presenta algunas dificultades con respecto a otros. Si bien es verdad que existen librerías/APIs dedicadas a superar este pequeño handicap. A continuación veremos ejemplos de dos tipos de librerías para analizar un documente XML desde java. Uno de ellos es el DOM (Document Object Model) y otro es el SAX (Simple API from XML).

Las diferencias principales entre DOM y SAX es que DOM genera un arból de objetos con sus dependencias en memoria. Esto permite acceder a cualquier elemento en cualquier posición una y otra vez, atrás y adelante sin problemas. El problema es que consume mucha memoria y no sería una opción recomendable para XMLs muy grandes. SAX por otro lado no almacena información en memoria y lee el fichero secuencialmente hasta encontrar el elemento y la información que necesitas en un proceso en donde se registran métodos callback cada vez que se detecta determinados patrones en el documento (apertura de etiquetas XML por ejemplo). SAX podría manejar con mayor facilidad grandes ficheros XML pero sin la libertad del DOM.

Veamos como podemos analizar este fragmento de XML


<?xml version="1.0" encoding="UTF-8"?>
<personas>
 <persona sexo="masculino">
  <nombre>Pepe</nombre>
  <apellidos>Gracia Perez</apellidos>
 </persona>
 <persona sexo="femenino">
  <nombre>María</nombre>
  <apellidos>Suarez Martinez</apellidos>
 </persona>
</personas>

Primero hay que crear un objeto Document (org.w3c.dom.Document) empleando otros dos objetos DocumentBuilder (javax.xml.parsers.DocumentBuilder) y DocumentBuilderFactory (javax.xml.parsers.DocumentBuilderFactory). Si por ejemplo el fichero que contiene nuestro xml se llama test.xml

Podríamos poner para cargar el dom el siguiente fragmento de código

(Dejando los namespaces completos)


org.w3c.dom.Document dom;
javax.xml.parsers.DocumentBuilderFactory dbf;
javax.xml.parsers.DocumentBuilder db;

dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();

try
{
  db = dbf.newDocumentBuilder();
  dom = db.parse("test.xml");
}
catch(Exception ex) {}

Ahora dom contiene toda la información y estructura de nuestro documento en memoria. Veamos como extraer la información que necesitamos

Para obtener el nodo raiz, en este caso personas, llamamos a:


org.w3c.dom.Element rootElement = dom.getDocumentElement();

rootElement es el objeto que ahora debemos interrogar. Por ejemplo si llamamos al método getElementsByTagName(String etiqueta) obtendremos un objeto de tipo NodeList (org.w3c.dom.NodeList) que contiene a su vez todos los posibles elementos incluidos dentro de la etiqueta. Para obtener por ejemplo el contenido de las etiquetas persona podríamos hacer


org.w3c.dom.NodeList nodeList = rootElement.getElementsByTagName("persona");

Para iterar sobre nodeList podriamos hacer


if(nodeList != null && nodeList.getLength()>0
{
  for(int i=0;i<nodeList.getLength();i++)
  {
    org.w3c.dom.Element element = (Element)nodeList.item(i);
    if(element.hasAttribute("sexo")) System.out.println(element.getAttribute("sexo"));
    org.w3c.dom.NodeList nodeList2 = element.getElementsByTagName("nombre");
    if(nodeList2 != null && nodeList2.getLength()>0
    {
      org.w3c.dom.Element el = (Element)nodeList2.item(0);
      System.out.println("Nombre: " + el.getFirstChild().getNodeValue());
    }
  }
}

Importante saber los métodos de nodeList:

– getLength() devolviendo el tamaño de la lista de nodos
– item(i) devuelve el nodo (objeto Node) de índice i

Y los métodos de Element

– getElementsByTagName(String nombreTag) devolviendo un NodeList
– getFirstChild() primer elemento inferior del nodo
– getAttribute(String atributo) valor del atributo
– hasAttribute(String atributo) si el nodo tiene o no este atributo

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *