XPath tiene una filosofía muy simple, ya que se basa de utilizar expresiones al estilo de un path, como el de un directorio de disco, a través de los nodos del archivo XML. A ésto se le une una multitud de posibilidades, como búsqueda de ciertos elementos a partir de un valor o una máscara.
Pero para entender mejor todo ésto, lo mejor es utilizar un ejemplo e ir viendo poco a poco qué se puede hacer. Pero he de advertir que este artículo es una pequeña introducción a XPath, y en él no se ve ni una décima parte de las posibilidades que nos ofrece esta tecnología.
Comencemos por un archivo XML simple:
<?xml version="1.0" encoding="UTF-8" ?>
<libro>
<titulo>Neraclem</titulo>
<autor>Rafael Hernamperez</autor>
<fecha>8 de Octubre de 2006</fecha>
<capitulo num="1">
<parrafo num="1">
Julian creyo despertar de un extrano sueno cuando abrio sus pesados ojos.
</parrafo>
<parrafo num="2">
El aturdimiento entorpecia sus movimientos, y no se atrevio a ponerse de pie.
<enlace url="http://rafinguer.spaces.live.com">El Rincon de la Felicidad</enlace>
Cerro nuevamente sus ojos, e intento despejar su confusa mente. Todo parecia dar vueltas y estaba algo mareado.
</parrafo>
</capitulo>
<capitulo num="2">
<parrafo num="1">
Todo era blanco inmaculado. Ni frio ni calor. Ni ligero ni pesado. Cerro los ojos, reteniendo momentaneamente aquel blanco absoluto. Poco a poco, el blanco se fue haciendo gris y, por ultimo, negro.
</parrafo>
<parrafo num="2">
Abrio los ojos, descubriendo que se hallaba en una enorme sala, tan alta como la estancia que acababa de abandonar.
</parrafo>
<parrafo num="3">
Giro lentamente 360 grados, asombrado por la majestuosidad de aquella magnifica e impresionante biblioteca de miles de libros ancestrales, que descansaban en no menos majestuosas estanterias.
<enlace url="http://rafinguer.blogspot.com">Tecnologia</enlace>
Habia libros de todos los tamanos, colores y grosores. Todos tenian una encuadernacion artesana, de piel, con lomos trabajados en relieve y con titulos de oro. Alla donde Julian miraba, se perdaa en libros y mas libros.
</parrafo>
</capitulo>
</libro>
Es posible navegar a través de los elementos, utilizando la barra o slash:
/
Con ésto nos situamos en la raíz del documento (antes del elemento "libro").
/libro
Con ésto estamos situados en el directorio libro, que está bajo el nodo raíz (de un nodo raíz pueden colgar directamente varios nodos).
Es posible buscar y localizar un nodo a partir de un valor de un atributo determinado. Para ello, se utiliza una expresión con esta sintaxis:
[@atributo="valor"]
Por ejemplo:
/libro/capitulo[@num="2"]
Se situaría en el nodo capítulo 2.
Con la doble barra, se accede directamente al primer elemento o nodo que se llame así, a partir de la ubicación actual.
//parrafo
Acceso al párrafo 1 del nodo capítulo 2 (en la expresión anterior ya nos habíamos situado en dicho nodo).
Para obtener el valor de un determinado atributo, se utiliza una expresión como la siguiente:
@atributo
Como, por ejemplo:
/libro/capitulo[@num="1"]/parrafo[@num="2"]/enlace/@url
Si se desea obtener el texto de un determinado elemento, se utiliza la expresión
text()
Como en el siguiente ejemplo:
/libro/autor/text()
Las expresiones vistas hasta ahora se pueden combinar unas y otras, consiguiendo la mayor parte de accesos al documento XML. No obstante existen muchas más expresiones con las que poder sacar más provecho a esta tecnología (ver enlaces al final).
XPath en Java
Para el ejemplo aquí expuesto se han utilizado los IDE's JBuilder 2006 y NetBeans 5, con JSDK v1.5.
La primera operación a realizar es obtener el documento XML:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document XMLDoc = factory.newDocumentBuilder().parse(new InputSource(new
FileInputStream("c:\\demoXML.xml")));
A continuación, especificar que se trabaja en modo elemento:
Element element = XMLDoc.getDocumentElement();
El siguiente paso es crear un objeto de tipo XPath:
XPath xpath = XPathFactory.newInstance().newXPath();
Y un objeto para utilizar expresiones asociadas a dicho objeto:
XPathExpression exp;
A continuación se crean las expresiones, compilándolas de la siguiente manera:
exp = xpath.compile("/libro/titulo/text()");
Por último, para obtener el texto del elemento, se utilizaría la siguiente sentencia:
System.out.println((String) exp.evaluate(element, XPathConstants.STRING));
Por supuesto, todo ello encerrado en un
try/catch
, para capturar y controlar las excepciones.El siguiente código muestra todo lo explicado:
import java.io.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
public class DemoXPath {
public DemoXPath() {
}
public static void main(String[] args) {
DemoXPath demoxpath = new DemoXPath();
try {
XPath xpath = XPathFactory.newInstance().newXPath();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document XMLDoc = factory.newDocumentBuilder().parse(new InputSource(new
FileInputStream("c:\\demoXML.xml")));
Element element = XMLDoc.getDocumentElement();
XPathExpression exp;
exp = xpath.compile("/libro/titulo/text()");
System.out.println("1.-" + (String) exp.evaluate(element, XPathConstants.STRING));
exp = xpath.compile("//fecha/text()");
System.out.println("2.-" + (String) exp.evaluate(element, XPathConstants.STRING));
exp = xpath.compile("/libro/capitulo[@num=\"1\"]//parrafo/text()");
System.out.println("3.-" + (String) exp.evaluate(element, XPathConstants.STRING));
exp = xpath.compile("//capitulo[@num=\"1\"]/parrafo[@num=\"2\"]/text()");
System.out.println("4.-" + (String) exp.evaluate(element, XPathConstants.STRING));
exp = xpath.compile("//parrafo[@num=\"3\"]/text()");
System.out.println("5.-" + (String) exp.evaluate(element, XPathConstants.STRING));
exp = xpath.compile("/libro/capitulo[@num=\"2\"]//parrafo[@num=\"3\"]/enlace/@url");
System.out.println("6.-" + (String) exp.evaluate(element, XPathConstants.STRING));
exp = xpath.compile("/libro/capitulo[@num=\"2\"]//parrafo[@num=\"3\"]/enlace/text()");
System.out.println("7.-" + (String) exp.evaluate(element, XPathConstants.STRING));
}
catch (Exception ex) {
System.out.println("Error: " + ex.toString());
}
}
}
El resultado obtenido sería el siguiente:
1.-Neraclem
2.-8 de Octubre de 2006
3.-
Julian creyo despertar de un extrano sueno cuando abrio sus pesados ojos.
4.-
El aturdimiento entorpecia sus movimientos, y no se atrevio a ponerse de pie.
5.-
Giro lentamente 360 grados, asombrado por la majestuosidad de aquella magnifica e impresionante biblioteca de miles de libros ancestrales, que descansaban en no menos majestuosas estanterias.
6.-http://rafinguer.blogspot.com
7.-Tecnologia
El ejemplo visto se ha basado en la lectura del XML a partir de un fichero guardado en el disco. Si se quisiera tratar el documento XML desde una URL (como un servlet o un web service), la variación estaría en la obtención del documento XML, concretamente, en el objeto
Document
:
Document XMLDoc=factory.newDocumentBuilder().parse(new InputSource(new URL(uri).openStream()));
Espero que este artículo os sea de gran utilidad.
ENLACES:
XPath desde la W3C
API XPath
Artículo de Sun Microsystems
Artículo XPath en castellano
Tutorial de XPath en castellano
Otro tutorial en castellano