viernes, mayo 29, 2009

XPath y NameSpaces

El problema: Trabajando con eXist-db, una base de datos XML, requería consultar los documentos almacenados de manera "directa". El problema radicaba en que los documentos responden a una estructura donde está definido el NameSpace del XML.

Por esto la única manera de acceder a los datos era haciendo una consulta igualando nombres, tal como lo hace el ETL Spoon (de la suite Pentaho) cuando se transforman XML, ie:
//*[name()='etiqueta']/text() para rescatar el valor de texto de todos los nodos etiqueta (que eventualmente puede ser distinto debido a que el contenido de etiqueta sea otro conjunto de nodos).

//*[name()='etiqueta' and text()='valor']/text() para acceder al valor de un nodo en particular, cuyo valor es valor. Esto sirve como referencia cuando se mezclan condiciones.

//*[name()='etiqueta' and text()='valor']/text()//root() para acceder a toda la estructura XML que contiene a etiqueta.

Pueden ir imaginándose las variaciones tóxicas.

Solución: Declarar el NameSpace, de manera de hacer las consultas de manera directa, al estilo de la vieja escuela, ie:
//etiqueta
//
etc.

Para ello, en mi caso con los códigos de acceso a eXist-db se incorpora la siguiente línea, luego de la inicialización del XPathQueryService:
service.setNamespace(prefijo, namespace);

En la aplicación cliente de eXist, se debe ejecutar en consola la instrucción (no documentada):
map prefijo=uri
El prefijo viene dado por lo que aparece normalmente arriba en los XML, algo que tiene la forma
<mixml xmlns="http://www.uri.com/miXml" mio="http://www.uri.com/miXml"></mixml>

Cuando sucede que, como en el ejemplo, el atributo xmlns va sin acompañante, y todas las etiquetas están sin el prefijo, es porque el namespace aplica a default, por ende el prefijo será nulo, o vacío.
Era mi caso, asi que en la consola de eXist puse:
map =http://www.uri.com/miXml
(doble espacio)
y en mi código:
service.setNamespace(null, "http://www.uri.com/miXml");

Referencias:
  • http://www.ziritione.org/blog/programming/java/dom4j-xpath-y-namespaces
  • http://weblogs.asp.net/wallen/archive/2003/04/02/4725.aspx
  • http://sourceforge.net/mailarchive/message.php?msg_name=200309180838.27341.meier%40ifs.tu-darmstadt.de
  • http://sourceforge.net/mailarchive/message.php?msg_id=CC371D02-54CA-11D8-8FAE-000A95782782%40apache.org

No hay comentarios.: