Vous êtes sur la page 1sur 40

UNIDAD 9.

Almacenamiento de la informacin Xquery

ndice de contenido
1.- Sistemas de almacenamiento de la informacin.........................................................................1 2.- Utilizacin de XML para almacenamiento de la informacin....................................................5 3.- Lenguajes de consulta manipulacin..........................................................................................6 4.- XQUERY....................................................................................................................................8 5.- Consultas (Flwor a HTML)......................................................................................................18 6.- Actualizacin (insercin, borrado, modificacin)....................................................................31 7.- Exportacin de libreras XML..................................................................................................36 8.- Otras funciones o libreras........................................................................................................37 9. Ejemplo Cooperativa Agraria....................................................................................................38

1.- Sistemas de almacenamiento de la informacin.


Una Base de Datos (BD) es una herramienta que permite organizar los datos que tienen algn tipo de relacin entre s, de manera que son almacenados y utilizados a travs de un interfaz de comunicacin que facilita su gestin dentro de una entidad u organizacin. Existen muchas maneras de clasificar los distintos tipos de bases de datos pero podemos resumirlo segn la variabilidad de los datos que se almacenen en ellas: Datos estticos: Datos que nunca cambiaran en el tiempo (solo lectura). Datos dinmicos: Datos que pueden modificarse de cualquier manera, a lo largo del tiempo. Salvo contadas excepciones (datos histricos, estadsticas, anlisis clnicos que nunca cambiarn desde que se tomaron), las bases de datos que se utilizan hoy en da son dinmicas. Las bases de datos estticas suelen utilizarse cuando se requiere un alto rendimiento en las consultas, quedando muy penalizadas si tuviera que actualizarse algn dato posteriormente. Los datos que se almacenan en ellas, deben seguir un modelo lgico adecuado para cumplir su funcin de manera eficiente. Es decir, de alguna manera hay que indicar a la base de datos qu cosas quiere almacenar, enviando una descripcin de los datos de inters. Solo as ser posible tener un modelo de datos adecuado al problema que se quiera dar solucin. Dependiendo de cmo se haya hecho esta descripcin de los datos, as cambiarn los procedimientos de acceso, almacenaje y recuperacin de los contenidos. Por tanto, dependiendo del modelo de datos utilizado podemos distinguir:

BD Jerrquica: Utilizan rboles para almacenar la informacin (nodo raz, nodos padre/hijos, nodos hoja), de manera que la extraccin de los datos se realiza mediante un recorrido del rbol y eligiendo la rama por la que debe continuar su bsqueda. Este tipo de estructuras son muy eficientes en las bsquedas pero no pueden reflejar eficientemente la redundancia de datos. BD de Red: Muy parecida a las jerrquicas pero donde un nodo puede tener varios padres simultneamente (en contraposicin de las bases de datos jerrquicas). BD Relacional: Es una base de datos que permite resolver el problema que tenan las bases de datos jerrquicas (las redundancias). Mientras que las jerrquicas la posicin del dato en
Pag: 1/40

Enrique Mora Moral.

el rbol era importante, en las relacionales es irrelevante. Un conjunto de datos compacto y con sentido propio se almacena en algo llamado tupla. Una tupla no es ms que una fila de una tabla en la que se almacena dicha informacin compacta. El conjunto de tuplas con informacin semntica igual determina una tabla. Y un conjunto de tablas pueden ser relacionadas con otras tablas (o tuplas), mediante tablas intermedias que reflejan las relaciones entre cada una de ellas. Esto es lo que soluciona la redundancia de informacin y son las ms utilizadas actualmente. BD Transaccional: Utilizan el concepto de transaccin (que veremos ms adelante) que permite asegurar una serie de caractersticas importantes en los sistemas informticos de hoy en da. Estas caractersticas se incluyeron en la mayora de las bases de datos relacionales de hoy en da. BD Multidimensional: A efectos sera una base de datos Relacional en el que en vez de tener tablas (2D), tendramos estructuras con N dimensiones para almacenar la informacin (cubos si fuese 3D). BD Orientadas a Objetos: Difiere de las bases de datos relacionales en que no se almacena la informacin por tuplas sino por objetos que contienen la informacin y los mtodos que son necesarios para tratarlas. Es llevar la programacin orientada a objetos al mundo de las bases de datos generando caractersticas como la herencia, la encapsulacin o el polimorfismo.

Como puede observarse, dependiendo del modelo de datos que se quiera almacenar, se deber utilizar una base de datos u otra. Independientemente del modelo usado, cuando se tiene un gran conjunto de bases de datos, lo comn es utilizar un Sistema de Gestin de Bases de Datos o SGBD, que unifiquen las bases de datos entre s y se mejoren los flujos de distribucin de la informacin en diferentes entornos y/o formatos. Para obtener ms informacin, vea la pgina http://www.maestrosdelweb.com/principiantes/que-son-las-bases-de-datos/. Bsicamente se deja de utilizar los almacenes de informacin de las aplicaciones (los ficheros) para utilizar un interfaz de comunicacin nico (el SGBD y una BD concreta). Su utilizacin permite: Evitar la redundancia de datos que puede producirse por la duplicacin de los mismos ficheros de datos utilizados en distintas aplicaciones y/o ubicaciones. Permiten la abstraccin de los datos independientemente del sistema hardware/software utilizado y del soporte utilizado para su almacenamiento. Evitar la inconsistencia de los datos cuando diferentes programas intentan actualizar un dato que es compartido. Evitar que el cambio o adicin de nueva informacin no planeada en el anlisis inicial del sistema obligue a la adaptacin de todos los programas informticos que utilizan esos ficheros. Evitar que la mala programacin en el acceso/modificacin/borrado de los datos en un fichero genere problemas de seguridad. Tener una capa de aplicacin y una capa de datos distinta facilita la depuracin y la trazabilidad de los programas. La abstraccin, independencia, consistencia, seguridad y accesibilidad son los objetivos que se buscan en estos sistemas. Adems su funcionamiento suele ser muy simple. Se puede resumir en un comentario muy acertado de D. ngel Garca Moreno, catedrtico de la Universidad Politcnica de
Enrique Mora Moral. Pag: 2/40

Madrid y profesor de la asignatura de Bases de Datos en la Ingeniera Informtica: "Mientras que con los mtodos clsicos se acceda a la informacin a travs de ficheros y los datos paseaban por los programas; en los SGBD son los programas los que se dan una vuelta por las Bases de Datos para conseguir lo que necesitan". Estos beneficios hacen que la prctica totalidad de los sistemas que quieran almacenar informacin recurran a un sistema de bases de datos acorde a sus necesidades, garantizando: Gestionar la redundancia para evitarla o al menos limitarla. Mantener los datos separados de las aplicaciones que lo usan. Localizar los datos en una ubicacin desde la cual, las aplicaciones puedan acceder de manera distribuida, concurrente y asegurando la integridad de los mismos. Permite realizar una correcta poltica de copias de seguridad, ya que ya no es necesario ir copiando los ficheros en distintas ubicaciones. En un SGBD no todo son ventajas. Existen una serie de inconvenientes que es necesario resaltar para tomar en el futuro una decisin adecuada. Como inconvenientes se pueden enumerar los siguientes: Un SGBD no es fcilmente administrable. Requiere de personal especializado en administracin de sistemas y lenguajes de consultas contra las bases de datos. Una buena administracin de los sistemas y de las bases de datos puede salvar la continuidad del negocio. Si los datos son simples y no requiere de acceso concurrente de usuarios o aplicaciones, puede ser sustituido por un simple fichero, como por ejemplo un archivo binario o un fichero XML. No es sencillo formar al personal que trabaja con los datos almacenados en un SGBD si no tiene un perfil orientado hacia la informtica. El personal de nminas de una empresa, por ejemplo, no tiene porqu aprender un lenguaje de programacin de consultas. Requerir que el sistema le proporcione una interfaz de comunicacin tipo formulario de consultas que oculte la complejidad del sistema. Poner en funcionamiento un SGBD requiere de un coste inicial en hardware y software que puede no ser necesario para las necesidades normales de un entorno pequeo. Siempre habr que realizar un anlisis de los beneficios y los inconvenientes que aportan la integracin de estos SGBD en un entorno de trabajo concreto. Un requisito que hasta el momento no se ha nombrado y que por exigencias del mercado se ha aadido en los SGBD modernos es el soporte transaccional. Una transaccin es un conjunto de rdenes en secuencia que, en su conjunto, determina un trabajo completo. El trabajo es completo si y solo si se cumplen todas y cada una de sus operaciones en el orden dado. Tras la ejecucin de una transaccin solo existen dos resultados posibles: Finalizada con xito. No completada (y asegura que no se ha cambiado nada). Veamos un ejemplo de cmo de importante es una transaccin. Supongamos que un usuario quiere sacar dinero de un cajero automtico. La transaccin es "sacar dinero". Para ello se siguen una serie de pasos secuenciales que permiten realizar la transaccin con xito: 1.Validacin del usuario (insercin del PIN). 2.Seleccin del importe a sacar.
Enrique Mora Moral. Pag: 3/40

3.Anotacin en la cuenta bancaria del reintegro. 4.Expedir tique y el dinero solicitado al usuario. Si est en el paso nmero 3 y despus hubiera un corte en el suministro elctrico, el usuario tendra anotada en su cuenta bancaria un reintegro que nunca ha sido entregado al usuario (paso 4). Obviamente el usuario se enfadara y reclamara. Una transaccin, si es ejecutada de manera exitosa, asegura que los pasos del 1 al 4 se han seguido en ese orden y que todo ha salido bien. Si la transaccin no ha sido exitosa, asegura que ni el dinero ha salido por el cajero, ni que tampoco se ha anotado el reintegro en la cuenta bancario del usuario (incluso aunque haya habido un corte en el flujo elctrico y estuviese la transaccin en el paso 3). Es decir, al no ser exitosa la transaccin es como si nunca hubiese pasado. Esto que, explicado con un ejemplo es tan simple, su nombre tcnico en un SGBD se denomina caractersticas ACID, acrnimo de: Atomicidad (Atomicity): Es la propiedad que asegura que una transaccin no se ha quedado a medias. O se ha ejecutado completamente o ninguna de las acciones intermedias ha sido llevada a cabo en la base de datos. Consistencia (Consistency): Una vez se ha determinado que la transaccin ha sido exitosa, debe quedar reflejados sus resultados en la base de datos dejando totalmente consistente e integra la base de datos. Aislamiento (Isolation): Una transaccin no puede afectar a otra en el transcurso de su ejecucin. Esto implica que dos transacciones que trabajen sobre el mismo conjunto de informacin no puede generar informacin inconsistente o error alguno en el sistema. Durabilidad (Durability): Una vez realizada la transaccin, sus resultados permanecern inalterables, independientemente de si surgen problemas en el sistema. Esto no quiere decir que una transaccin posterior no pueda modificar los datos anteriormente modificados (s podra pero no de manera concurrente con otra transaccin). Hasta el momento no se ha hablado de cmo est definido un SGBD, por lo que se podra pensar que es un nico bloque funcional, hecho ad hoc, para resolver un problema de almacenamiento de datos concreto. En realidad un SGBD puede verse como un conjunto de actores y componentes que se intercomunican entre s para hacer ms fcil el acceso a los datos. Estos componentes son: El Hardware: Dispositivos fsicos donde residen todos los dems componentes del SGBD. Normalmente son dispositivos con capacidades de redundancia y con alta disponibilidad para soportar cualquier contingencia que surja durante su funcionamiento. El Software: Aplicacin que permite abstraerse de las caractersticas fsicas del hardware y que permite hacer al SGBD ser independiente de la plataforma hardware sobre la que se ejecuta. Los Datos: Informacin almacenada dentro del recinto fsico (hardware) y administrada por el software. Los Usuarios: Actores a los que se les permite interactuar con el SGBD, hacindoles transparente el acceso a los datos, independientemente del Hardware o Software utilizado. En relacin a los usuarios, depender del software SGBD que se vaya a utilizar pero genricamente podemos identificar los siguientes roles: Administrador del Sistema informtico. Administrador de la Base de datos y Consultas. Usuario Final.

Enrique Mora Moral.

Pag: 4/40

Los anteriores componentes se unen entre s haciendo que el sistema sea modular y fcil de usar/administrar.

nicamente queda por hablar del sistema hardware que se debe utilizar para llevar a cabo la instalacin de un SGBD. Para pequeas y medianas empresas cualquier servidor relativamente moderno puede servir. Todo depender del grado de concurrencia de accesos y la cantidad de datos a almacenar los que determinarn las caractersticas fsicas del hardware. Pero lo que debe ser fundamental es el dimensionamiento del almacn de datos para que no se quede pequeo. Desde la mquina analtica de Charles Babbage hasta los netbook de hoy en da, el almacenamiento de la informacin ha pasado por muchas etapas: El cableado fsico. La tarjeta perforada. La cinta mgnetica. El disco duro. Los disquetes. El CD-ROM / DVD. Las tarjetas de memoria. Los pendrives. Los discos duros en estado slido. Es claro que los discos duros actuales estn alcanzando tamaos impensables, lo que el almacenamiento de datos puede no ser un problema. Simplemente sustituyendo un disco por otro de mayores dimensiones el problema se resuelve y adems es seguro que ser ms rpido que el antiguo (lo que aceleran las transferencias de informacin).

2.- Utilizacin de XML para almacenamiento de la informacin.


Cualquiera que sean los datos que se almacenen, si se hace en formato XML, su estructura se simplifica como consecuencia de los principios de orden y jerarqua que incorpora todo documento
Enrique Mora Moral. Pag: 5/40

XML. Ello permite representar muchas clases de datos, incluso aquellos procedentes de fuentes no XML. Al hablar de introducir el tema de la consulta en un documento XML es obligado analizar las posibilidades que existen de emular en este terreno, las posibilidades que conocemos existen con el uso de SQL en el modelo relacional, que es la gran referencia en Informtica para la consulta de datos. Vamos a resear las diferencias existentes entre datos XML y datos relacionales: a) Metadatos: los datos relacionales presentan estructuras regulares y homogneas (cada fila tiene las mismas columnas con los mismos nombres y tipos) lo que permite usar metadatos sin ningn problema, mientras en XML los datos son heterogneos e irregulares (pgina web, captulo de libro, etc.) con estructuras diferentes que deben describirse caso a caso, de forma que estos metadatos se acaban describiendo en el propio documento. b) Anidamiento: los documentos XML contienen distintos niveles de anidamiento, que son irregulares e impredecibles, mientras que los datos relacionales son planos al estar organizados a partir de tablas. c) Jerarqua: en XML existe una jerarqua y un orden intrnseco que no se da en la estructura relacional, ello se refleja en la forma de trabajar de XPath (el quinto objeto rojo, los objetos que estn despus de A y antes de X, etc.) cuando este orden y esta jerarqua carece de relevancia en el modelo relacional. d) Densidad: los datos relacionales son densos (cada columna un valor) y los inexistentes se declaran como tales (con null), en cambio los datos en XML son dispersos, y la informacin que no existe sencillamente carece de elemento. Como consecuencia XML es ms libre que el modelo relacional a la hora de enfrentarse con datos faltantes. e) Mecanismo de consulta: en XML el resultado de una consulta consiste inevitablemente en una secuencia heterognea de elementos, atributos y valores primitivos, que a su vez pueden servir de intermediarios para procesar una expresin de mayor nivel, cosa que difiere de SQL, donde toda expresin dentro de una consulta devuelve una tabla. Ello significa que un lenguaje de consulta para XML debe proporcionar necesariamente funciones constructoras que sean capaces de crear en el proceso estructuras anidadas que pueden ser complejas; se trata de requisitos que en cambio son irrelevante en el caso relacional con el uso de SQL. Ante las consideraciones anteriores, que conducen a la conclusin de que no siempre las cosas que pueden ser objeto de consulta en un documento lo puedan ser en una Base de Datos relacional y viceversa, W3C decidi que las consultas en XML deban ser objeto de un nuevo lenguaje, que se llam XQuery.

3.- Lenguajes de consulta manipulacin.


Mientras que en Informtica consultar es acceder a datos ya almacenados sin que durante el proceso se cree otra cosa que no sea el propio resultado de la bsqueda, en el caso de XML, no slo se consulta en el concepto habitual, sino que adems se obtiene un fragmento de XML como resultado de ello. En consecuencia, una consulta XQuery tiene como entrada y salida sendos documentos XML, con lo que ste no es slo un lenguaje de consulta que opera sobre documentos (para ser ms preciso, sobre instancias de un modelo de datos XML) sino que tambin genera documentos XML a demanda de la consulta correspondiente. Por ello, los requisitos puestos por W3C a XQuery son: Clausura del modelo: toda consulta y todo resultado debe obedecer a un mismo modelo de datos, esto es: ser cerrado respecto al modelo de datos Xquery. Compatibilidad con los Esquemas: ello supone disponer tanto de un conjunto de tipos primitivos como de la posibilidad de definir nuevos tipos, con un mecanismo que adems
Enrique Mora Moral. Pag: 6/40

incorpore el correspondiente proceso de validacin. Compatibilidad con XPath: al basarse en este lenguaje de localizacin de la familia XML, se pueden identificar las partes de un documento y con ello recuperar la informacin deseada. Posibilidad de Composicin: la totalidad de las distintas expresiones basadas en XPath sean condicionales o cualquieras otras, deben poder combinarse entre ellas con la mxima generalidad. Ello significa en la prctica, que el resultado de cualquier expresin se debe poder usar como operando de otra. Completitud: aunque sin conseguir una potencia expresiva comparable a la completitud del modelo relaciona], XQuery debe ser capaz de obtener un documento XML construido a partir de documentos diferentes, siempre usando para ello el clculo de predicados de primer orden y las funciones recursivas. Generalidad: el lenguaje debe poder aplicarse tanto en entornos que usen tipos de datos muy estrictos y bien especificados, como en otros, donde los tipos de entrada y salida se descubran en tiempo de ejecucin, e incluso con datos que carezcan de cualquier tipado. En otras palabras, XQuery debe poder trabajar con documentos descritos de formas muy distintas, sea un Esquema, una DTD o incluso carecer de cualquier descripcin. Semntica: no deben existir grandes restricciones semnticas a la hora de proporcionar el resultado de una consulta. Esta exigencia es debida al hecho de que la obtencin de un valor en estas consultas puede consistir en ninguno, uno o muchos tems, que a su vez pueden ser elementos, atributos o valores primitivos, lo que hace que sea necesario que todo operador XQuery tenga bien definidas todas las posibilidades que puedan aparecer. El cumplimiento de lo anterior conduce inevitablemente a una semntica compleja, y al objeto de simplificarla en XQuery se definen operadores con operaciones implcitas. As por ejemplo, los operadores aritmticos que se utilicen (como +) cuando se aplican a un elemento, automticamente extraen su valor numrico, mientras que por su parte los operadores de comparacin (como =) aplicados a una secuencia de valores, de forma automtica, iteran buscando los valores que satisfagan la comparacin. Como puede verse se trata de trabajar con los mayores grados de libertad posible en la semntica a la hora de efectuar una consulta. Anlisis esttico: asumiendo que el proceso de consulta tiene dos fases: anlisis y evaluacin (parecido a la compilacin y ejecucin de un programa.) en XQuery se optimiza el anlisis y el proceso de deteccin de errores, decidindose automticamente qu errores se permiten y cules no. De estos requisitos se constata que el objetivo de XQuery se centra mucho ms en la recuperacin de informacin que en la actualizacin de documentos ya existentes, por lo que en la prctica las consultas XQuery tienden a ajustarse a las tareas que puedan interaccionar con aquellas cosas que ya estn almacenadas siguiendo la sintaxis de XML.

Enrique Mora Moral.

Pag: 7/40

4.- XQUERY
El modelo de datos de XQuery se basa en representar los datos XML en forma de nodos y valores, que sirven de operandos y resultados de los operadores XQuery. En este modelo se representa uno o ms documentos XML con una secuencia definida como una coleccin de uno o ms tems, donde un tem es un nodo o un valor atmico. Dos caractersticas importantes son: 1) Los nodos en XQuery se corresponden con los siete nodos del modelo XPath (documento, elemento, atributo, etc.) 2) Los valores atmicos usados a corresponden con los tipos simples predefinidos de los Esquemas (cadenas, booleanos, decimales, etc.). En el modelo XQuery cada nodo elemento o atributo consta de: nombre (una cadena) anotacin de tipo valor tipado, tal como lo determina el proceso de validacin en Esquemas y en el caso de que estuviera sin validar o sin tipo adopta la anotacin xs:anyType. Como se observa, el modelo XQuery se apalanca en la estructura XML que ya conocemos, de forma que toda consulta se basa en el rango de datos que usa el documento analizado, esto es, un rbol etiquetado y ordenado, cuyos nodos tienen una identidad que puede estar asociada a tipos de datos simples o complejos. Ello permite que XQuery pueda usarse tanto para consultar documentos con datos sin tipar, como gobernados por Esquemas, o aquello que obedece a una DTD. XQuery es un lenguaje funcional cuya sintaxis es la de XML aunque parecida a la de XPath, con lo que toda consulta es una expresin que debe evaluarse. Adelantemos que una consulta acerca de todos los ttulos de los captulos de un documento como personas.xml, se puede hacer con la expresin tal como: doc("personas.xml ")/personas/persona/nombre Con este ejemplo intentamos extraer los nombres de las personas almacenadas en nuestro documento personas.xml. Como era lgico pensar, una expresin XQuery puede estar compuesta de otras de ms bajo nivel que se combinan mediante operadores y palabras clave, de forma que tras su anlisis, toda expresin acaba siendo una secuencia heterognea de nodos y valores atmicos. Podemos realizar consultas a colecciones. Las consultas a colecciones nos consultan varios ficheros XML almacenados en un directorio a la vez. Por ejemplo, para consultar los <nif> de las personas de todos los ficheros p*.xml: for $p in collection("./?select=p*.xml")/personas/persona/nif return $p Se pueden construir XML directamente con XQUERY con la siguiente sintaxis: element curso { attribute fechaNacimiento { 1996}, element p {"Nombre de la primera persona"}, element p { doc("personas.xml")/personas/persona[1]/nombre } }
Enrique Mora Moral. Pag: 8/40

Donde puede utilizar constantes y valores extrados con XQUERY para montar una estructura fija. El resultado de la anterior consulta devuelve: <?xml version="1.0" encoding="UTF-8"?> <curso fechaNacimiento="1996"> <p>Nombre de la primera persona</p> <p> <nombre> nombre5</nombre> </p> </curso> Donde este segundo nombre lo ha extrado del fichero anterior.

4.1. Definiciones bsicas


Un literal es la clase ms simple de expresin XQuery, y representa un valor atmico. En consecuencia sus valores se corresponden con los tipos simples de Esquema, donde los tipos numricos son xs:integer, xs:decimal, y xs:double y los tipo cadena se delimitan por comillas pudiendo contener referencias a entidades predefinidas. Una variable en XQuery es un nombre que empieza con el signo dlar ($a) o con el mismo nombre que una etiqueta ($nif) que se asocia a un valor y que se usa dentro en una expresin para representarlo. Una forma de dar valores a una variable es por medio de una expresin let que asocia una o varias variables y luego evala la correspondiente expresin interna. Un constructor es una funcin que crea un valor de un tipo particular a partir de una cadena que contiene la representacin lxica del tipo deseado; por ejemplo: string($persona/nif) Los distintos tipos de valores atmicos se crean llamando a un constructor, que en general tiene el mismo nombre que el tipo que construye. Una transformacin es el paso de una instancia del modelo de datos a otra instancia de este modelo, dejando abierto tanto el origen de los datos de entrada como la forma corno se enva el resultado a la aplicacin que haya invocado esta transformacin. Para identificar los datos de entrada existen dos funciones bsicas: doc() que devuelve un documento completo identificndolo con una URI; por ejemplo: doc(personas.xml) y collection() que devuelve cualquier secuencia de nodos asociada a la URI (a menudo usada para identificar la base de datos empleada en la consulta). Por tanto, una consulta puede tener su entrada bien por medio de doc, collection, o bien referenciando alguna parte de un contexto externo. Se habla de un error dinmico si las funciones doc() y collection() no localizan lo especificado en ellas. Una consulta consta de dos partes: prlogo (querv prolog) y cuerpo (querv body). El prlogo consta de una serie de declaraciones que definen el entorno para el procesado del cuerpo, que consta de una expresin cuyo valor proporciona el resultado de la consulta. El prlogo se usa cuando el cuerpo depende de los espacios de nombres, Esquemas o funciones, y cuando ello ocurre la consulta depende en gran medida de lo especificado en l. Como ejemplo de la forma de trabajar, sea el documento personas.xml :
Enrique Mora Moral. Pag: 9/40

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE personas SYSTEM "file:/media/Datos/Curso11-12/proyecto1/personas.dtd"> <personas> <persona edad="25"> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion> calle 1</direccion> <poblacion>pueblo1</poblacion> <telefono> 23 </telefono> </persona> <persona codigo="c2"> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle 2</direccion> <poblacion>pueblo1</poblacion> <telefono>33 </telefono> </persona> <persona codigo="c3"> <nif>nif3</nif> <nombre>nombre3</nombre> <direccion>calle 3</direccion> <poblacion>pueblo2</poblacion> <telefono>34 </telefono> </persona> <persona> <nif>nif4</nif> <nombre>nombre4</nombre> <direccion>calle 4</direccion> <poblacion>pueblo2</poblacion> <telefono>34 </telefono> </persona> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> <direccion> calle 5</direccion> <poblacion>pueblo3 </poblacion> <telefono> 45 </telefono> </persona> <persona> <nif>nif6</nif> <nombre> nombre6</nombre> <direccion> calle 6</direccion> <poblacion>pueblo3 </poblacion> <telefono> 15 </telefono> </persona> </personas>

y veamos cmo obtener el sumario con el nif y nombre de cada persona, cosa que podemos hacer mediante: <resumenPersonas> { for $persona in doc("personas.xml")/personas/persona return <resumenPersona> { string($persona/nif)} --- {string($persona/nombre)} </resumenPersona>
Enrique Mora Moral. Pag: 10/40

} </resumenPersonas> Generando el siguiente resultado <?xml version="1.0" encoding="UTF-8"?> <resumenPersonas> <resumenPersona>nif1 --- nombre1</resumenPersona> <resumenPersona>nif2 --- nombre2</resumenPersona> <resumenPersona>nif3 --- nombre3</resumenPersona> <resumenPersona>nif4 --- nombre4</resumenPersona> <resumenPersona>nif5 --- nombre5</resumenPersona> <resumenPersona>nif6 --- nombre6</resumenPersona> </resumenPersonas> donde se observa cmo tras la etiqueta de inicio del elemento se crea la variable $persona a la que se asigna una secuencia de nodos con el uso de la palabra clave in que precede al documento que proporciona esta secuencia, terminando con /personas/persona que selecciona cualquier elemento Capitulo del documento objeto de la consulta. Por su parte, la sentencia return define la salida para cada nodo que aparece en la secuencia definida por la variable $persona.

4.2. Tipos de datos en Xquery


Puesto que un documento XML puede contener una gran variedad de informacin, un lenguaje de consulta debe evitar todas las suposiciones previas que puedan terminar generando conflictos con los datos que se vayan a encontrar; con ello, el programador podr centrarse en el tratamiento del documento sin tener que entrar en excesivas sutilezas acerca del sistema de tipos que maneje en cada caso. Por ello, recordando los requisitos puestos a XQuery, ste debe estar en condiciones de poder procesar documentos tan distintos corno:

Los tipados (uso de tipos xs, xsd) con Esquemas o Relax NG, lo que supone contar con un lenguaje de consulta con datos estticos fuertemente tipados, lo que evita un gran nmero de errores. Los gobernados por otros lenguajes de esquema como DTDs. Los usados con una visin procedente de otro sistema no XML, como sera el caso de un Sistema de Gestin de Base de Datos relacional.

Obsrvese que las fuentes de datos pueden tener estructuras muy complejas, y por ello las expresiones deben estar bien definidas para que se est en condiciones de poder evaluar cualquier estructura. Por ello, XQuery se especific para trabajar con datos poco o muy tipados, siendo su sistema de tipos uno de sus aspectos ms tiles, eclcticos e inusuales que existen. Como conclusin, retngase que para encarar esta variedad de situaciones, XQuery permite escribir consultas con muy poca informacin sobre tipos. Ello es factible gracias a la capacidad de XQuery para obtener y utilizar la informacin de tipos en tiempo de ejecucin, siendo capaz, a pesar de ello, de poder detectar posibles errores antes de que la consulta se ejecute del todo. Si el documento XML manejado obedece slo a una DTD o incluso si carece de cualquier esquema,
Enrique Mora Moral. Pag: 11/40

los tipos son muy reducidos: documento, elemento, ID, IDREF, etc., con lo que el documento incorpora poca informacin referida a tipos, y por ello las consultas se hacen confiando en un conjunto de reglas, de tal manera que durante el proceso de ejecucin se pueda inferir el tipo apropiado para poder obtener el valor buscado. En cambio, cuando XQuery se enfrenta con tipos de datos derivados de Esquemas XML, debe distinguir mucho ms, y en con-secuencia debe estar en condiciones de manejar, por un lado, los tipos predefinidos accesibles en toda consulta, y por otro, los tipos importados para la consulta desde un Esquema especfico. Esta flexibilidad de XQuery debe ser apreciada debidamente.

4.3. Sistema de tipos: XQuery bsico


Puesto que el sistema de tipos de datos de XQuery se basa en Esquemas, hay que distinguir dos conjuntos de tipos: los predefinidos, accesibles por cualquier consulta, y los importados para una consulta desde un Esquema concreto. Se llama XQuery Bsico al mecanismo que admite por un lado la importacin de Esquemas para hacerlos accesible a la consulta, y por otro, la posibilidad de utilizar un tipado esttico que permita que una consulta pueda contrastarse con los Esquemas importados, de forma que se puedan localizar los posibles errores antes de acceder a los datos. Es importante hacer notar que con el mecanismo XQuery bsico, una consulta no necesita importar ningn Esquema para poder utilizar tipos predefinidos, ya que estn contenidos en el propio documento, y el modelo de datos preserva esta informacin de tipos, permitiendo con ello que las consultas accedan a ellos. As, aunque una consulta no importe Esquema alguno, se pueden usar sin problemas los correspondientes tipos simples que se encuentren presentes en los datos del documento. Lo dicho no obsta para que en el caso de que la consulta utilice una lgica relacionada con el significado de un Esquema, sea aconsejable proceder a su importacin, cosa que para hacerse debe ser tenido en cuenta por la aplicacin que vaya a generar la consulta. Hagamos notar que al ser secuencias los valores habituales en XQuery, los tipos usados para describirlos se llaman tipos secuencia, que pueden ser bien tipos predefinidos, y por ello ser usados en cualquier consulta, o bien estar definidos en un Esquema, los cuales deben importarse previamente. Como se ha dicho, a las implementaciones XQuery se les requiere que detecten errores de tipo, cosa que unas veces puede hacerse antes de que se ejecute la consulta y otras slo duran-te la ejecucin, cuando se evale la expresin correspondiente. A la primera posibilidad se le llama tipado esttico y se efecta usando simultneamente la informacin importada y la propia de la consulta. Un procesador dotado de tipado esttico por tanto puede detectar determina-dos tipos de errores mediante la simple comparacin de la consulta con el Esquema importado, lo que significa que no se requiere acceder a los datos para encontrar tales errores.

4.4. Capacidades de XQuery


Al objeto de resumir las potencialidades de XQuery, en lo que resta de captulo nos enfrentaremos a tres apartados, cuya razn de ser ya hemos introducido:

El manejo de los rboles de XQuery. La combinacin y reestructuracin de los documentos XML obtenidos. Los cuantificadores, operadores y funciones propias de XQuery.
Pag: 12/40

Enrique Mora Moral.

Como ejemplo de referencia de este proceso usaremos el documento personas.xml incluido en el apartado 4.1 de esta unidad. Con la siguiente estructura:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT personas (persona)* > <!ELEMENT persona (nif, nombre, direccion, poblacion, telefono) > <!ELEMENT nif (#PCDATA) > <!ELEMENT nombre (#PCDATA) > <!ELEMENT direccion (#PCDATA) > <!ELEMENT poblacion (#PCDATA) > <!ELEMENT telefono (#PCDATA) > <!ATTLIST persona edad CDATA #IMPLIED > <!ATTLIST persona codigo ID #IMPLIED >

4.5. Recorrer y construir rboles en XQuery


Para presentar las expresiones y operaciones bsicas que permiten recorrer y construir rboles con XQuery, usaremos el marco de las distintas tareas a llevar a cabo: a)La localizacin de nodos utilizando expresiones basadas en trayectos XPath. b)La obtencin de estructuras XML usando constructores. c)La extraccin de tipos. Localizacin de nodos en estructuras XML Para que XQuery cumpla su objetivo, sus expresiones deben poder localizar nodos empezando por determinar el documento en el que efectuar la bsqueda. Por ejemplo: doc("personas.xml")/personas/persona abre el documento personas.xml obteniendo su nodo documento, con /personas se selecciona este elemento y con /personas/persona se obtienen estos elementos dentro de personas. En el caso de que en este proceso se vayan a necesitar variables, stas se definen en el prlogo de la consulta, de forma que una vez declaradas son accesibles en cualquier punto. As, si los nombres de las personas en personas.xml van a usarse varias veces en una consulta, tiene sentido definir una variable, tal como: $nombre Los predicados XPath como mtodos para filtrar secuencias de nodos se generalizan en XQuery de forma que el valor de una expresin siempre sea una secuencia heterognea de nodos y valores atmicos. Son ejemplo de su funcionamiento:

doc("personas.xml") /personas/persona[nif="nif1"] que devuelve slo aquellas personas que tengan como nif el valor nif1 doc("personas.xml") /personas/persona[3] devuelve la tercera persona de mi lista

En la lnea de las expresiones XPath, una expresin en XQuery puede empezar con / o //. En el primer caso la bsqueda se inicia en el nodo raz, mientras que el significado del operador //, en
Enrique Mora Moral. Pag: 13/40

trminos del modelo de datos, es dar acceso a todos los atributos y descendientes de los nodos que aparecen en su izquierda en el documento considerado; por ejemplo:

doc ( "personas.xml" ) //nombre cualquier nombre del sistema. doc (" libros . xml" ) / / @edad elementos que tenga definido el atributo edad.

Igual que en XPath, las wildcards permiten que las consultas seleccionen sin especificar sus nombres completos; por ejemplo: doc("personas.xml")//persona[4]/* obtiene los elementos/etiquetas una a una de la cuarta persona, est o no en el espacio de nombres, ya que las expresiones XQuery soportan espacios de nombres, lo que permite distinguir nombres procedentes de vocabularios diferentes. Hagamos notar que debido a que durante el proceso de evaluacin de toda expresin XQuery siempre se devuelven nodos del documento sealado, si en ella hubiera algo que no correspondiera a uno de estos nodos aparecer un error de tipo.

Construccin de estructuras XML


Una vez localizados los nodos en un documento, se debe crear el resultado que satisface la consulta, cosa que se hace mediante el uso de constructores; esta capacidad de construir nuevos objetos XML es una de las funcionalidades ms importantes de XQuery. La sintaxis para ello se basa en la evaluacin de una expresin que aparece entre llaves y que obviamente no tiene el mismo significado que en la notacin XML, ya que mientras en XQuery el smbolo { es el inicio de una expresin a evaluar, en XML slo es un carcter. As: <peso>123.45</peso> es un elemento de nombre peso que contiene un literal, mientras que: <peso>{$peso * 0.85}</peso> es un elemento construido cuyo contenido se calcula evaluando una expresin. De esta forma mezclamos elementos contantes como la etiqueta <peso> con elementos evaluados como el resultado de evaluar la variable peso y multiplicarlo por 0.85. Incluso se repiten las constantes del estilo <peso> cuando utilizamos bucles FOR. La tecnologa es semejante a la usada por PHP contra HTML a la hora de generar documentos dinmicos. Una vez proporcionado explcitamente un constructor por medio de { }, la consulta se inicia creando un nodo documento que empieza siendo vaco y que acaba rellenndose con el resultado correspondiente, hasta crear un documento completo. Las expresiones delimitadas por { } siempre estn encargadas de evaluar y crear contenidos de elementos o atributos; por ejemplo: <ejemplo> <p> Esta es una consulta </p> <eg> doc("personas.xml")//persona[1]/nombre </eg> <p> Este es el resultado de la consulta anterior.</p> <eg>{ doc("personas.xml")//persona[1]/nombre }</eg>
Enrique Mora Moral. Pag: 14/40

</ejemplo> produce el documento: <?xml version="1.0" encoding="UTF-8"?> <ejemplo> <p> Esta es una consulta </p> <eg> doc("personas.xml")//persona[1]/nombre </eg> <p> Este es el resultado de la consulta anterior.</p> <eg> <nombre>nombre1</nombre> </eg> </ejemplo> El primer doc("personas.xml")//persona[1]/nombre se comporta como una constante, mientras que el segundo es sustituido por el resultado de evaluar la expresin anterior. Las expresiones incluidas en los constructores de elementos permiten crear nuevos valores XML reestructurando los existentes, como vamos a contar el numero de personas de nuestro fichero: <numero> {count(doc("personas.xml")/personas/persona)} </numero> se obtiene el documento: <?xml version="1.0" encoding="UTF-8"?> <numero>6</numero> Debe hacerse notar, aunque no mostremos ningn ejemplo, la posibilidad existente de enlazar constructores de forma sucesiva, creando con ello constructores sucesivamente ms complejos que van anidando elementos y atributos.

Extraccin de tipos
En un lenguaje de bsqueda, los tipos de datos permiten comprobar la correccin tanto de la propia consulta como de las operaciones a los que se va a someter los datos de la respuesta; en base a ello, XQuery aprovecha que los Esquemas XML proporcionen un conjunto de tipos predefinidos y la posibilidad de definir nuevos tipos para manejar los tipos de datos involucrados en una consulta. Por ello, en el prlogo de toda consulta deben figurar explcitamente los Esquemas que se van a importar, identificndolos por su espacio de nombres, de forma que durante el correspondiente proceso de validacin los nodos elemento y atributo puedan adquirir sus notaciones de tipo correspondientes. Recordemos que en el caso de que no se usen Esquemas, todos los nodos elemento tienen por defecto como notacin tipo xs:anyType. La consecuencia a retener es que la falta de definicin de tipos no impide que se puedan efectuar consultas con XQuery; por ejemplo: <media> {avg( doc("personas.xml")/persona/persona/telefono )} </media> calcula el valor medio de la etiqueta telefono en nuestro ejemplo, aunque no hayamos usado un Esquema o Relax sino un DTD, y el elemento telefono no esta bien tipado. Para que ello sea
Enrique Mora Moral. Pag: 15/40

posible, cuando avg() requiere un argumento numrico, automticamente cada valor de telefono se convierte a doble precisin y se calcula la media requerida. Esta conversin implcita siendo muy til cuando se trabaja con datos no tipados puede no ser ptima, como en el caso del ejemplo que se acaba de ver, donde el precio se representara mucho mejor por un decimal. Obviamente, si en el proceso de consulta existiese un Esquema que declarase telefono un campo peso como decimal, la media se calculara usando nmeros decimales. Consecuencia de lo anterior es la necesidad de conocer la forma como XQuery trata las distintas casusticas que pueden aparecer durante el procesado de un documento. As, por ejemplo, si nos encontramos con una expresin como: 1 * $b, hay que preguntarse cmo se interpretara si $b adoptara las distintas posibilidades existentes (por ejemplo que fuera una secuencia vaca, o un dato de caracteres sin tipar o un elemento, o una secuencia de cinco nodos, etc.). Este tipo de cuestiones es bsico que puedan resolverse, debido a la propia flexibilidad del XML, lo que obliga a que casos como stos deben quedar bien definidos a lo largo del proceso de consulta. Para hacer frente a esta necesidad, en XQuery existe una operacin bsica llamada extraccin de tipo, cuyo significado es evidente. Este proceso de extraccin de tipo permite que tengan sentido expresiones como: doc("personas.xml")/personas/personas/[nombre='nombre1'] donde siendo nombre un elemento y `nombre1' una cadena, se pueda asumir que pueden ser iguales. La clave reside en que el operador = extrae el tipo de valor del elemento, obteniendo que es una cadena, lo que permite a XQuery poderla comparar con 'nombre1' y tomar la decisin que corresponda. En lnea con lo anterior, adelantemos que XQuery incorpora la funcin data() que extrae directamente el tipo del valor correspondiente; por ejemplo: <resultado> {data( <e xsi:type="xs:integer">4</e> )} </resultado> una vez validado hace que se obtenga directamente como resultado el entero 4, sin tener que preocuparse del tipo de dato concreto. <?xml version="1.0" encoding="UTF-8"?> <resultado>4</resultado> En este proceso se esta evaluando al tirn el cdigo XML que se encuentra dentro de la funcin data. Lo normal es que se evale una variable que contiene una etiqueta.

Veamos lo que ocurre en el caso del elemento precio, segn el tipado que incorpore el operador (por simplicidad adelantamos el uso de dos de ellos, de evidente significado eq y gt):

Si se carece de tipo, se trata como una cadena y en consecuencia slo puede compararse con otra cadena. Este sera el caso de la consulta: for $b in doc("personas.xml")//persona where $b/poblacion eq "pueblo1"

Enrique Mora Moral.

Pag: 16/40

return $b/nombre

Si los datos dependen de una DTD, no se pueden usar los tipos simples de los Esquemas, con lo que el telefono no tiene tipo. Por ello en la siguiente consulta, es necesario pasar telefono a decimal: for $b in doc("personas.xml")//persona where xs:decimal($b/telefono) gt 33.00 return $b/nombre Devolviendo: <?xml version="1.0" encoding="UTF-8"?> <nombre>nombre3</nombre> <nombre>nombre4</nombre> <nombre> nombre5</nombre>

Si quien gobierna los tipos es un Esquema que declara telefono para ser un decimal, nada de lo anterior es necesario.

Como norma general en XQuery, los datos objeto de consulta se interpretan como datos tipados, y se fuerza a la consulta a tenerlos que interpretar antes de compararlos, con la nica excepcin de que sean cadenas o que efectivamente contengan los tipos adecuados. El hecho de que los Esquemas tengan tipos predefinidos permite usarlos para escribir funciones similares a las de los lenguajes de programacin convencionales, aprovechando las estructuras de XML. Como ejemplo, una funcin que eleva al cuadrado los telefonos: declare function local:cuadrado ($p as xs:integer) as xs:integer {$p * $p}; for $telefono in doc("personas.xml")//telefono return <cuadrado> {local:cuadrado ($telefono)} </cuadrado> de forma que la expresin $e/.. del documento instancia ser cierto cuando se evale para este nodo. A pesar de lo dicho, la posibilidad de trabajar con datos poco tipados en ocasiones es una ventaja no despreciable que el buen uso de XQuery puede explotar. Como ejemplo, adelantndonos a secciones siguientes, consideremos el caso de una funcin que devuelva una secuencia de tems en el orden inverso al existente en el documento, una situacin en la que parece razonable que no se especifique ni el tipo del parmetro de la funcin, ni el tipo que ser devuelto, ya que es razonable que esta funcin pueda aplicarse a cualquier secuencia de tems; por ejemplo: declare function local:reverse($items) { let $count := count($items) for $i in 0 to $count return $items[$count - $i] }; let $persona := doc("personas.xml")/personas/persona return local:reverse($persona)

Enrique Mora Moral.

Pag: 17/40

el operador to genera sucesiones de persona girandolas con la funcin reverse. Al no especificar ningn tipo, ni para los parmetros ni para el resultado, podra usarse para devolver una secuencia de cualquier otro tipo de datos.

5.- Consultas (Flwor a HTML)


En XQuery las consultas combinan informacin de una o ms fuentes por lo que necesariamente sta debe reestructurarse para obtener el resultado deseado. Para efectuar estas tareas existen una serie de expresiones, llamadas FLWOR (de las iniciales de FOR, LET, WHERE, ORDER y RETURN que se pronuncia como en ingls flower) que juegan un papel similar al de las instrucciones SELECT-FROM-WHERE de SQL al asociar valores a variables para poder obtener resultados.

Clusulas FLWOR
Se llama tupla a una combinacin de variables asociadas a una expresin FLWOR formada por las clusulas for o/y let, seguidas por where o/y order y obligatoriamente por return, ya que invariablemente algo se devuelve como consecuencia de una consulta; por ejemplo: for $b in doc("personas.xml")/personas/persona where $b/@edad = 25 return $b/nombre devuelve las personas cuya edad es 25, asociando la variable $b a cada persona para crear una serie de tuplas. En este ejemplo where comprueba si $b/@edad es igual a 25 de forma que return se evala para cada tupla que satisfaga la condicin. El resultado que se obtiene es: <?xml version="1.0" encoding="UTF-8"?> <nombre>nombre1</nombre> Las clusulas for y let Toda expresin FLWOR incorpora al menos una de estas clusulas, existiendo distintas combinaciones posibles para ellas. As en: for $i in (1, 2, 3) return <tupla><i>{ $i }</i></tupla> se crea un elemento tupla donde $i se asocia a (1, 2, 3) para construir una sucesin de enteros, dando como resultado: <?xml version="1.0" encoding="UTF-8"?> <tupla> <i>1</i>
Enrique Mora Moral. Pag: 18/40

</tupla> <tupla> <i>2</i> </tupla> <tupla> <i>3</i> </tupla> En cambio la clusula let asocia una variable al resultado global de una expresin y si no existen en ella ninguna clusula for, se crea una sola tupla. Si en el anterior se usa let en lugar de for, esto es: let $i := (1, 2, 3), el resultado es una nica tupla, donde la variable $i est limitada a la secuencia entera de enteros: let $i := (1, 2, 3) return <tupla> {$i} </tupla> Con el siguiente resultado: <?xml version="1.0" encoding="UTF-8"?> <tupla>1 2 3</tupla> Cuando let se usa en combinacin con una o ms clusulas for, las variables asociadas a let se aaden a las tupas generadas por las clusulas for; por ejemplo: for Si in (1, 2, 3) let $j := (1, 2, 3) return <tupla><i>{ Si }</i><j>{ $j }</j></tupla> obtiene como resultado: <tupla><i>1</i><j>1 2 3</j></tupla> <tupla><i>2</i><j>1 2 3</j></tupla> <tupla><i>3</i><j>1 2 3</j></tupla> En el siguiente ejemplo se muestra la relacin entre let y return:
(: cada return debe completar un cdigo XML valido :) (: se puede engaar devolviendo en una funcin una lista de nodos :) declare function local:clientes ($p1) { let $cliente := doc("facturacion.xml")/facturacion/clientes/cliente[nif = $p1] return (<td> {$cliente/nif} </td> , <td> {$cliente/nombre} </td>)}; <html> <body> {for $factura in doc("facturacion.xml")/facturacion/facturas/factura let $c3 := doc("facturacion.xml")/facturacion/clientes/cliente[nif = $factura/nif] return <table> <tr> <td> {string($factura/numero)} </td> <td> {string($factura/fecha)} </td></tr> <!-- la variable y es global dentro de todo el buble mostrando los valores de forma correcta permite mezclas con factura recomendacin --> <tr> <td> {$c3/nif} </td> <td> {$c3/nombre} </td> </tr> <tr> <td> {$factura/nif} </td> <td> {$c3/nombre} </td> </tr> <!-- engao con una funcin que devuelve una lista de nodos de dificil utilidad--> <tr> {local:clientes (string($factura/nif))} </tr>
Enrique Mora Moral. Pag: 19/40

<!-- Declaracin de la variable donde se cierra y se abre una elemento dentro del bucle en casos concretos, funciona como una funcin --> <tr> {let $c2 := doc("facturacion.xml")/facturacion/clientes/cliente[nif = $factura/nif] return ( <td> {$c2/nif} </td> , <td> {$c2/nombre} </td> ) } </tr> </table>} </body> </html>

La clusula where Esta clusula elimina las tupas que no satisfacen una determinada condicin, de forma que return slo se evala para aquellas personas cuya edad supere los 25 aos. Quedando: for $p in doc("personas.xml")/personas/persona where $p/@edad > 25 return $p
d ando

como resultado, ningn elemento para nuestro caso.

Podemos consultar las personas que no incluyen el atributo edad. for $p in doc("personas.xml")/personas/persona where not($p/@edad ) return $p Aunque su anlogo en SQL WHERE slo comprueba valores simples, esta restriccin no se da en XQuery, donde la clusula where puede contener cualquier expresin que se evale a un valor booleano. Aunque sea una expresin compleja sobre los sug-elementos de un objeto.

La clusula order
Esta clusula ordena las tupas antes de evaluar return, con el objeto de poder cambiar el orden del resultado. As, para ordenar alfabticamente las personas por nombre en orden descendente se puede escribir: for $p in doc("personas.xml")/personas/persona order by $p/nombre descending return $p Por defecto se considera orden ascendente y se pueden mezclar varios ordenes de forma arbitraria: for $p in doc("personas.xml")/personas/persona order by $p/nombre descending, $p/@edad, $p/poblacion descending return $p

La clusula return
Enrique Mora Moral. Pag: 20/40

Esta clusula est en toda expresin FLWOR y tambin es comn en los elementos constructores. As por ejemplo, la siguiente consulta reduce nuestro fichero de personas al nif y el nombre eliminando el resto de los elementos: <personas> {for $p in doc("personas.xml")/personas/persona return <persona> { $p/nif, $p/nombre } </persona> } </personas> el resultado que se obtiene es: <?xml version="1.0" encoding="UTF-8"?> <personas> <persona> <nif>nif1</nif> <nombre>nombre1</nombre> </persona> <persona> <nif>nif2</nif> <nombre>nombre2</nombre> </persona> <persona> <nif>nif3</nif> <nombre>nombre3</nombre> </persona> <persona> <nif>nif4</nif> <nombre>nombre4</nombre> </persona> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> </persona> <persona> <nif>nif6</nif> <nombre> nombre6</nombre> </persona> </personas> Existen una gran variedad de aplicaciones del uso de los constructores de elementos con una clusula return. Por ejemplo, la tarea de insertar un elemento direccin que mezcle los campos direccin y poblacin en una nica etiqueta: <personas> {for $p in doc("personas.xml")/personas/persona return <persona> { $p/nif, $p/nombre } <direccion> {concat(data($p/direccion), data($p/poblacion))} </direccion></persona> } </personas>

Enrique Mora Moral.

Pag: 21/40

la consulta tiene como resultado: <?xml version="1.0" encoding="UTF-8"?> <personas> <persona> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion> calle 1pueblo1</direccion> </persona> <persona> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle 2pueblo1</direccion> </persona> <persona> <nif>nif3</nif> <nombre>nombre3</nombre> <direccion>calle 3pueblo2</direccion> </persona> <persona> <nif>nif4</nif> <nombre>nombre4</nombre> <direccion>calle 4pueblo2</direccion> </persona> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> <direccion> calle 5pueblo3 </direccion> </persona> <persona> <nif>nif6</nif> <nombre> nombre6</nombre> <direccion> calle 6pueblo3 </direccion> </persona> </personas> Podemos separar direccin de poblacin o incluso meter la poblacin entre parntesis basta con: <personas> {for $p in doc("personas.xml")/personas/persona return <persona> { $p/nif, $p/nombre } <direccion> {concat(data($p/direccion), " (", data($p/poblacion),")")} </direccion></persona> } </personas>

Expresiones condicionales
En XQuery se utilizan expresiones condicionales de la misma forma que en otros lenguajes, por lo que aparece en XQuery tanto la clusula if como then y else. Comenzamos modificando nuestro fichero de personas con la siguiente estructura: <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT personas (persona)* >
Enrique Mora Moral. Pag: 22/40

<!ELEMENT persona (nif, nombre, direccion, poblacion, telefono,gastos) > <!ELEMENT nif (#PCDATA) > <!ELEMENT nombre (#PCDATA) > <!ELEMENT direccion (#PCDATA) > <!ELEMENT poblacion (#PCDATA) > <!ELEMENT telefono (#PCDATA) > <!ELEMENT gastos (gasto)* > <!ELEMENT gasto (fecha, valor) > <!ELEMENT fecha (#PCDATA) > <!ELEMENT valor (#PCDATA)> <!ATTLIST persona edad CDATA #IMPLIED > <!ATTLIST persona codigo ID #IMPLIED > Sobre esta estructura modificamos nuestros datos, ajustando los gastos de estas personas:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="hoja1.xsl"?> <!DOCTYPE personas SYSTEM "file:/media/Datos/Curso11-12/proyecto1/personas.dtd"> <personas> <persona edad="25"> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion> calle 1</direccion> <poblacion>pueblo1</poblacion> <telefono> 23 </telefono> </persona> <persona codigo="c2"> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle 2</direccion> <poblacion>pueblo1</poblacion> <telefono>33 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>100</valor> </gasto> <gasto> <fecha>2012-02-01</fecha> <valor>200</valor> </gasto> </gastos> </persona> <persona codigo="c3"> <nif>nif3</nif> <nombre>nombre3</nombre> <direccion>calle 3</direccion> <poblacion>pueblo2</poblacion> <telefono>34 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>300</valor> </gasto> </gastos>
Enrique Mora Moral. Pag: 23/40

</persona> <persona> <nif>nif4</nif> <nombre>nombre4</nombre> <direccion>calle 4</direccion> <poblacion>pueblo2</poblacion> <telefono>34 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>400</valor> </gasto> </gastos> </persona> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> <direccion> calle 5</direccion> <poblacion>pueblo3 </poblacion> <telefono> 45 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>500</valor> </gasto> </gastos> </persona> <persona> <nif>nif6</nif> <nombre> nombre6</nombre> <direccion> calle 6</direccion> <poblacion>pueblo3 </poblacion> <telefono> 15 </telefono> <gastos> </gastos> </persona> </personas>

Como ejemplo podemos obtener consultas complejas, como personas que tengan ms de dos gastos. for $p in doc("personas.xml")/personas/persona where $p/gastos/count(gasto) >= 2 return $p como resultado sale:
<?xml version="1.0" encoding="UTF-8"?> <persona codigo="c2"> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle 2</direccion> <poblacion>pueblo1</poblacion> <telefono>33 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>100</valor> </gasto> <gasto> <fecha>2012-02-01</fecha>
Enrique Mora Moral. Pag: 24/40

<valor>200</valor> </gasto> </gastos> </persona>

No es una sentencia condicional, pero aprovechando el count anterior puedo aadir una etiqueta <numeroDeGastos> al nif y al nombre de las personas que tengan dos gastos o ms. (>= 2): <personas> { for $p in doc("personas.xml")/personas/persona return <persona> {$p/nif, $p/nombre} { if ($p/gastos/count(gasto) >= 2) then <numeroDeGastos> {$p/gastos/count(gasto)} </numeroDeGastos> else () } </persona> } </personas> donde la secuencia vaca () se usa para especificar que una clusula no devuelve nada. El resultado que se obtiene es:
<?xml version="1.0" encoding="UTF-8"?> <personas> <persona> <nif>nif1</nif> <nombre>nombre1</nombre> </persona> <persona> <nif>nif2</nif> <nombre>nombre2</nombre> <numeroDeGastos>2</numeroDeGastos> </persona> <persona> <nif>nif3</nif> <nombre>nombre3</nombre> </persona> <persona> <nif>nif4</nif> <nombre>nombre4</nombre> </persona> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> </persona> <persona> <nif>nif6</nif> <nombre> nombre6</nombre> </persona> </personas>

Otro ejemplo, es el cambio del color de fondo en la cabecera de una tabla, aplicando la sentencia IF al valor del atributo BGColor:
<table> <tr bgcolor="{if ($factura/numero mod 2 = 0) then ("blue") else ("red") }"> <td> numero </td> <td> fecha </td> </tr>

Operar en XQuery
Enrique Mora Moral. Pag: 25/40

Aunque ya han sido utilizadas en algunos casos, veamos de forma ms sistemtica las piezas con las que se elaboran las consultas Xquery.

Cuantificadores
Para las consultas basadas en una condicin resulta bsico determinar tanto si existe al menos un tem que la satisfaga, como saber si todos los tems involucrados en ella lo hacen; ste es el mbito respectivo de los cuantificadores existencial y universal. Consideremos la consulta: for $p in doc("personas.xml")/personas/persona where some $g in $p/gastos/gasto satisfies ($g/valor > 400) return $p en ella, el cuantificador existencial some incluido en la clusula where se encarga de comprobar si existe al menos un gasto de una persona superior a 400. El resultado obtenido es la quinta persona con que presenta un gasto de 500:
<?xml version="1.0" encoding="UTF-8"?> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> <direccion> calle 5</direccion> <poblacion>pueblo3 </poblacion> <telefono> 45 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>500</valor> </gasto> </gastos> </persona>

Otra cosa es que el total de los gastos de una persona superar los 400. En este caso sera algo parecido a: for $p in doc("personas.xml")/personas/persona where sum ($p/gastos/gasto/valor) > 400 return $p En este caso devuelve el mismo valor, pero la consulta anterior es distinta a la que utiliza la clausula exist. El el primer caso busca la existencia de un gasto individual superior a 400, en el segundo busca que el total de sus gasto supere a 400. Por su parte, un cuantificador universal tiene la funcin de comprobar si todos los nodos de una determinada secuencia satisfacen la condicin objeto de la consulta. Por ejemplo, podemos seleccionar aquellas personas en las que cada uno de sus gastos supera los 200. for $p in doc("personas.xml")/personas/persona where every $g in $p/gastos/gasto satisfies ($g/valor > 200) return $p
Enrique Mora Moral. Pag: 26/40

Obtenindose como resultado:


<?xml version="1.0" encoding="UTF-8"?> <persona edad="25"> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion> calle 1</direccion> <poblacion>pueblo1</poblacion> <telefono> 23 </telefono> <gastos/> </persona> <persona codigo="c3"> <nif>nif3</nif> <nombre>nombre3</nombre> <direccion>calle 3</direccion> <poblacion>pueblo2</poblacion> <telefono>34 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>300</valor> </gasto> </gastos> </persona> <persona> <nif>nif4</nif> <nombre>nombre4</nombre> <direccion>calle 4</direccion> <poblacion>pueblo2</poblacion> <telefono>34 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>400</valor> </gasto> </gastos> </persona> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> <direccion> calle 5</direccion> <poblacion>pueblo3 </poblacion> <telefono> 45 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>500</valor> </gasto> </gastos> </persona> <persona> <nif>nif6</nif> <nombre> nombre6</nombre> <direccion> calle 6</direccion> <poblacion>pueblo3 </poblacion> <telefono> 15 </telefono> <gastos> </gastos> </persona>

Enrique Mora Moral.

Pag: 27/40

El operador every reconocido en lgica con all (todos), funciona correctamente y escoge la persona si todos sus gastos superan los 200. Presenta un problema, si no hay ningn gasto devuelve el valor verdadero, por eso aparece nif6 y nif1. Existe una relacin entre el operador all o (every) y el operador exist o (some). Estas reglas de la lgica son una ampliacin de las Leyes de Morgan sobre la negacin. x[condicin] = ~x[~condicin] x[condicin] = ~x[~condicin]

Operadores
En su mayora los operadores que se utilizan en XQuery coinciden con los habituales en el resto de lenguajes de programacin; los ms utilizados son los siguientes: Aritmticos: +, -, *, div, idiv, mod, todos con su significado convencional. Comparativos: tambin se corresponde con los operadores habituales conocidos: eq =, ne !=, lt <, le <=, gt >, ge >=. Debe sealarse que tanto estos operadores comparativos como los aritmticos, cuando se enfrentan a secuencias vacas, actan de la misma forma que SQL lo hace con los null. De posicin: XQuery proporciona dos operadores para determinar la posicin de dos nodos en el orden propio de un documento, que son tiles cuando por alguna razn el orden de los elementos sea significativo. El operador $a << $b devuelve cierto si $a precede a $b en el orden del documento y viceversa con $a >> $b. Ejemplo: for $p in doc("personas.xml")/personas/persona let $p4 := doc("personas.xml")/personas/persona[4] return if ($p >> $p4) then $p else () Con: let $p4 := doc("personas.xml")/personas/persona[4] Selecciono la cuarta persona de la lista de personas. Y: if ($p >> $p4) then $p else () Selecciono aquellas personas que estn detrs de esta cuarta persona. Resultando:
<?xml version="1.0" encoding="UTF-8"?> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> <direccion> calle 5</direccion> <poblacion>pueblo3 </poblacion> <telefono> 45 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>500</valor> </gasto>
Enrique Mora Moral. Pag: 28/40

</gastos> </persona> <persona> <nif>nif6</nif> <nombre> nombre6</nombre> <direccion> calle 6</direccion> <poblacion>pueblo3 </poblacion> <telefono> 15 </telefono> <gastos> </gastos> </persona>

De Secuencia: estos operadores actan combinando secuencias para obtener como resultado otra secuencia, sin cambiar el orden interno que stas tenan en el documento original; son stos: union, intersect, y except. Los operadores union (que tambin admite la forma lxica: | ) e intersect equivalen a las correspondientes operaciones conjuntistas, aunque ahora con secuencias de operandos. El operador except, parte de dos secuencias de nodos y devuelve otra con todos los nodos presentes en el primer operando que no figuran en la segunda. Debe sealarse que se pueden combinar estos operadores de secuencia, siempre que se mantenga el principio de que ningn nodo aparezca dos o ms veces. En el caso de que algn operando involucrado en estas operaciones contenga un tem que no sea un nodo se declara el error correspondiente. Ejemplo de union: for $p in doc("personas.xml")/personas/persona[1] union doc("personas.xml")/personas/persona[2] return $p Donde selecciono la primera y la segunda persona. Ejemplo de intersect o interseccin. Por ejemplo, personas de pueblo1 con el atributo edad: for $p in doc("personas.xml")/personas/persona[poblacion="pueblo1"] intersect doc("personas.xml")/personas/persona[@edad] return $p En este caso devuelve:
<?xml version="1.0" encoding="UTF-8"?> <persona edad="25"> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion> calle 1</direccion> <poblacion>pueblo1</poblacion> <telefono> 23 </telefono> <gastos/> </persona>

Que corresponde con el nico elemento que pertenece a los dos conjuntos. Ejemplo de execpt o diferencia. Son los elementos que estn en el primer grupo y no estn en el segundo. Por ejemplo: for $p in doc("personas.xml")/personas/persona[poblacion="pueblo1"] except doc("personas.xml")/personas/persona[@edad] return $p
Enrique Mora Moral. Pag: 29/40

Son las personas de pueblo1 no tienen definida la edad. En este caso devuelve:
<?xml version="1.0" encoding="UTF-8"?> <persona codigo="c2"> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle 2</direccion> <poblacion>pueblo1</poblacion> <telefono>33 </telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>100</valor> </gasto> <gasto> <fecha>2012-02-01</fecha> <valor>200</valor> </gasto> </gastos> </persona>

Funciones predefinidas
En XQuery existen todo un conjunto de funciones predefinidas muchas de las cuales son habituales en otros lenguajes y otras estn pensadas especficamente para procesar XML. Como en SQL son muy usadas funciones tales como: mino, max(), coun(), sum(), avg(), etc., cuyo significado, parmetros y resultados son suficientemente evidentes. Otras funciones familiares de XQuery son las que operan sobre nmeros: round(), floor() y ceiling(), y sobre cadenas: concat(), string-length(), starts-with(), ends-with(), substring(), uppercase(), lower-case() que incluso pueden adaptarse para admitir como parmetros distintos tipos de datos simples. Respecto a las funciones propias de XML que no suelen estar en otros lenguajes, algunas de ellas ya las hemos definido y utilizado como es el caso de doc(). En este grupo son especialmente usadas: not(), empty() y exists(). La primera tiene el correspondiente significado booleano basado en negacin; empty() es una funcin que detecta si una secuencia es vaca; la funcin opuesta es exists(), que indica si una secuencia contiene al menos un tem. Adems de las citadas, hay que destacar aquellas funciones que acceden a tipos de informacin de un nodo, como string() que devuelve el valor de cadena de un nodo o la ya utilizada data(), que devuelve el tipo del valor del nodo. Ms especficamente, el valor de string() incluye la representacin del texto encontrado en el nodo y sus descendientes, concatenndolos segn el orden de aparicin en el documento; por ejemplo: string((doc("personas.xml")/personas/persona[1])) da como resultado la cadena el siguiente texto:
<?xml version="1.0" encoding="UTF-8"?> nif1 nombre1 calle 1 pueblo1 23
Enrique Mora Moral. Pag: 30/40

Para finalizar, es importante sealar que en XQuery es perfectamente posible crear funciones definidas por el usuario, construidas sobre la biblioteca bsica que proporciona el lenguaje. En particular estas funciones definidas por el usuario permiten abreviar consultas muy largas. Esta posibilidad de recurrir a XQuery desde otros lenguajes hace que las implementaciones XQuery forme parte de entornos de programacin basados en Java o C#, o incluso de sistemas de gestin de bases de datos relacionales, de forma que este entorno proporciona a XQuery tanto funciones externas como variables. El desarrollo de XQuery es uno de los ms laboriosos, pues depende de mltiples circunstancias, y debe tener en cuenta una gran cantidad de requisitos. Lo presentado en este captulo es slo una introduccin a estos puntos, con el objetivo de poner de manifiesto los problemas a los que se tiene que enfrentar la nueva Web para alcanzar todas sus posibilidades. A lo anterior hay que aadir el propio problema del desarrollo de Sistemas de Gestin de Bases de Datos que manejen documentos XML, un tema al cual nos referiremos brevemente en el ltimo captulo. pero que por el momento no forma parte de la familia XML.

6.- Actualizacin (insercin, borrado, modificacin)


Hasta el momento solo se ha podido realizar consultas sobre los contenidos ya almacenados en la base de datos XML. Quizs nuestro amigo quiera insertar, reemplazar, renombrar, cambiar y/o borrar entradas dentro de la base de datos. Para ello indicaremos qu hacer en cada caso. Para obtener ms informacin, vea las pginas http://www.xmlplease.com/xquery-update http://exist. sourceforge.net/update_ext.html http://stackoverflow.com/questions/ 5335046/xquery-update-insert-or-replace-depending-ifnode-exists-not-possible. Para poder manejar estos elementos es preciso ajustar Oxygen para que permita realizar operaciones de modificacin. El primer paso es cambiar desde Tools-External Tools-Preferences tenemos que cambiar la librera Saxon a Saxon-EE. En este caso Saxo-EE Xquery 9.3.0.5 u otra librera del mismo tipo. Depende de la versin de Oxygen instalado. Saxon-EE permite modificaciones.

Enrique Mora Moral.

Pag: 31/40

Una vez cambiada la libera Saxon tengo que comprobar que existe una extensin de archivos xu asociados asociado al Editor Xquery, se comprueba desde la misma ventana anterior buscando File Types, como se puede comprobar en la siguiente ventana:

Adems de esto es preciso configurar y ajustar el escenario de ejecucin para Saxon EE. El escenario de ejecucin Xquery se configura desde el siguiente Icono: Desde este punto accedemos a la configuracin de los escenarios:

Enrique Mora Moral.

Pag: 32/40

Donde ajusto el escenario por defecto a la librera Saxon-EE:

Una vez hechos estos procesos podemos comenzar a modificar nuestros documentos XML desde una consulta Xquery. RENOMBRADO DE NODOS. Es posible renombrar un elemento o grupo de elementos determinados. Se le puede cambiar el nombre a un nodo con la sentencia rename. Por ejemplo, podemos cambiar la primera etiqueta <nif> de una persona por la etiqueta <cif> con la siguiente sentencia: rename node doc("personas.xml")/personas/persona[1]/nif as "cif" El contenido de la etiqueta <nif> se pasa integro a la etiqueta <cif> y se tendra que comprobar la descripcin del documento y los tipos de datos en el proceso de cambio de dicha etiqueta. Rename funciona nodo a nodo. Si se quiere cambiar todos los nif de personas por cif se utilizara el siguiente cdigo:
for $nif in doc("personas.xml")/personas/persona/nif return rename node $nif as "cif"

Para volver a cambiar todos los cif por nif:


Enrique Mora Moral. Pag: 33/40

for $cif in doc("personas.xml")/personas/persona/cif return rename node $cif as "nif"

INSERCIN
Se quiera aadir un nuevo baile en la base de datos. Los datos son: La insercin se realizara de la siguiente manera: insert node <persona> <nif>nifnuevo</nif> <nombre>nombrenuevo</nombre> <direccion>calleNuevo</direccion> <poblacion>puebloNuevo</poblacion> <telefono>nuevo</telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>100</valor> </gasto> </gastos> </persona> before doc("personas.xml")/personas/persona[1] Este cdigo inserta el nodo indicado en fichero personas.xml". El nodo se insertar antes del primer nodo de la base de datos (por la clausula "before"). Si se quiere insertar despus, solo cambiara "before" por "after". Ambas utilizan como referencia al primer nodo ("[1]"). Una sentencia equivalente para insertar al principio del fichero, sin tener que referenciar a nodo alguno de la base de datos, sera sustituyendo la ltima lnea por esta otra: insert node <persona> <nif>nifnuevo</nif> <nombre>nombrenuevo</nombre> <direccion>calleNuevo</direccion> <poblacion>puebloNuevo</poblacion> <telefono>nuevo</telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>100</valor> </gasto> </gastos> </persona> as first into doc("personas.xml")/personas

Enrique Mora Moral.

Pag: 34/40

Cada vez que se pulsa una ejecucin introduce un nuevo elemento repetido, pasa exactamente lo mismo que con la sentencia insert en una base de datos. Si por el contrario, lo que se desea es insertar al final de la base de datos, sin referenciar a ningn nodo, se realizara de la siguiente manera: as last into doc("personas.xml")/personas Se puede incluso aadir una lista de nodos entre parntesis separados por comas:
insert node (<persona> <nif>nifnuevo1</nif> <nombre>nombrenuevo</nombre> <direccion>calleNuevo</direccion> <poblacion>puebloNuevo</poblacion> <telefono>nuevo</telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>100</valor> </gasto> </gastos> </persona>, <persona> <nif>nifnuevo2</nif> <nombre>nombrenuevo</nombre> <direccion>calleNuevo</direccion> <poblacion>puebloNuevo</poblacion> <telefono>nuevo</telefono> <gastos> <gasto> <fecha>2012-01-01</fecha> <valor>100</valor> </gasto> </gastos> </persona>) before doc("personas.xml")/personas/persona[1]

O seleccionar una variable y aadirlos al lote o uno a uno en un bucle for. Por ejemplo, repetir los de pueblo1 usando una variable: let $clnPbl1 := doc("personas.xml")/personas/persona[poblacion ="pueblo1"] return insert node $clnPbl1 before doc("personas.xml")/personas/persona[1]

MODIFICACIN.
Pues resulta, que antes se insertaron de forma automtica varios nodos idnticos. Se va a proceder a cambiar el nif del primero cambiando nifnuevo por nif-n1 La modificacin se realizara de la siguiente manera:
replace value of node
Enrique Mora Moral. Pag: 35/40

doc("personas.xml")/personas/persona[1]/nif with "nif-n1"

Se pueden realizar varias modificaciones a la vez, separndolas por comas. Cambiamos el nif del primero a nif-n1c y el del segundo a nif-n2c:
replace value of node doc("personas.xml")/personas/persona[1]/nif with "nif-n1c", replace value of node doc("personas.xml")/personas/persona[2]/nif with "nif-n2c"

Replace no permite modificar un lista de nodos entre parntesis, para modificar varios nodos es necesario usar un bucle for. Por ejemplo, fijar todas las poblaciones a Antequera:
for $poblacion in doc("personas.xml")/personas/persona/poblacion return replace value of node $poblacion with "Antequera"

BORRADO
Despus aadir y modificar elementos, podemos borrarlos. Por ejemplo, se van a borrar la primera y la segunda persona: delete node doc("personas.xml")/personas/persona[1], delete node doc("personas.xml")/personas/persona[2] Cuidado con los borrados mltiples que pueden dejar el fichero vaco. Delete permite borrar listas de nodos, por lo que es posible ejecutar el siguiente cdigo para borrar todos los clientes de Archidona: let $archidona := doc("personas.xml")/personas/persona[poblacion = "Archidona"] return delete node $archidona Aunque, es ms cmodo declarar la variable en un bucle for y borrar nodo a nodo.

7.- Exportacin de libreras XML


Despus de realizar todos los cambios en la base de datos, es un buen momento para exportar el contenido a un fichero XML externo. De esta manera se podra tener una copia de seguridad en caso de contingencia. Qizx Studio nos permite realizarlo de manera muy sencilla: 1. Ir a la pestaa "XML_Libraries". 2. Seleccionar "DB_BailesDeSalon.xml", botn derecho y pulsar "Export to File ...". Aparece una nueva ventana en la que se puede seleccionar el fichero de salida, la codificacin y el formato t.. (XML, HTML, XHTML, o texto). Para hacer una copia de seguridad se selecciona XML y se prodecer a volcar la informacin. Ver Figura 6.23.

Enrique Mora Moral.

Pag: 36/40

Figura Exportacin de libreras XML en Qizx Para finalizar, se habl anteriormente de cmo utilizar expresiones FLWOR para que devuelvan cdigo HTML. El procedimiento para exportar los resultados es muy sencillo. Una vez que se est en la pestaa "XQuery" y se ejecuta la consulta, en la parte derecha muestra los resultados. Hay que pusar el botn de exportacin de resultados "Save results" y aparecer una ventana similar a la de la Figura anterior. De esta manera tendremos en fichero los resultados de la consulta.

8.- Otras funciones o libreras.


Se ha visto que XQuery es una herramienta de alto nivel que permite realizar todas las tareas administrativas de un SGBD sin tener que programar ninguna lnea en C/C++ o Java. Pero XQuery no es solamente lo que se ha visto aqu. Recordemos que XQuery usa por XPath y ste tiene muchas funcionalidades que no se han tratado en este captulo. Existen funciones para acceder a nodos padre, funciones para tratamiento de valores numricos, para tratar strings, resolver URIs, funciones para tratar fechas/horas, para acceder a nodos, prig_establecer secuencias... En el caso de necesitar ms potencia a la hora de generar las consultas, se recomienda consultar las funciones de Xpath20. Otra manera de acceder a los nodos de los documentos XML es mediante la librera DOM (Document Object Model). DOM es una interfaz de programacin de aplicaciones (API), que permite representar documentos HTML y/o XML de manera que las aplicaciones que la utilicen puedan representar el documento en forma de rbol. Una vez cargado el rbol, se puede recorrer buscando informacin, modificando los propios nodos o la informacin que contienen, cambiando la estructura del rbol, etc. Esta API es un estndar de acceso aprobada por la W3C. El inconveniente es que es necesario conocer un lenguaje de programacin para hacer uso de esta API. En la actualidad la prctica mayora de los navegadores la tienen implementada. Por ltimo tenemos otra API llamada SAX (Simple API for XML). Es una librera que inicialmente se utilizaba en Java pero que en la actualidad es posible utilizarla en muchos lenguajes de programacin. La principal ventaja de usar un parser SAX es que el documento XML se lee una nica vez, de manera secuencial y sin que se cargue todo el en memoria (sin generar ningn rbol). Esto redunda en que los analizadores SAX son ms eficientes en la memoria utilizada que los DOM. Como desventaja es que una vez pasada la lectura, no se puede volver a atrs (en contraposicin de DOM que s se permite). En resumen, existen muchas maneras de manipular documentos XML. En este libro se ha elegido XQuery pues permite utilizarse en los grandes sistemas SGBD y tambin en pequeas aplicaciones con motores de BD XML nativas como Qizx. No ser necesario tener conocimientos de programacin en lenguajes como C/C++ o Java para manejar API's como SAX o DOM. En cualquier caso, la decisin final de utilizar una u otra solucin depender de las necesidades que
Enrique Mora Moral. Pag: 37/40

tenga el proyecto al que vaya a implantarse, haciendo especial hincapi en el almacenamiento y el tratamiento de la informacin.

9. Ejemplo Cooperativa Agraria.


Sobre el siguiente documento Relax NG:
datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes" element cooperativa { element socios { element socio { attribute numeroSocio { xsd:integer}, element nif {xsd:string}, element nombre {xsd:string}, element direccion {xsd:string}, element poblacion {xsd:string}, element telefono {xsd:string}, element saldo {xsd:decimal}}* }, element vales {element vale { attribute numeroVale { xsd:integer}, attribute numeroSocio {xsd:integer}, element fecha {xsd:date}, element peso {xsd:decimal}, element rendimiento {xsd:decimal}}* }, element gastos { element gasto { attribute numeroGasto {xsd:integer}, attribute numeroSocio {xsd:integer}, element fecha {xsd:date}, element descripcion {xsd:string}, element importe {xsd:decimal}}*}}

Donde podemos cargar los siguientes datos de prueba: Se pueden realizar las siguientes consultas Xpath: 1. Calcular el total de kilos de aceitunas que se han llevado a la cooperativa. /cooperativa/vales/sum(vale/peso) 2. Socios que tienen un saldo negativo y no han aportado aceitunas a la cooperativa. /cooperativa/socios/socio[saldo < 0 and not (@numeroSocio = /cooperativa/vales/vale/@numeroSocio)] 3. Mostrar vale o vales con el rendimiento ms alto de aceite en las aceitunas. /cooperativa/vales/vale[rendimiento = /cooperativa/vales/max(vale/rendimiento)] 4. Vales incorrectos. Son aquellos en los que no existe el socio, el peso es negativo o cero y el rendimiento no se encuentra entre 0 y 100. /cooperativa/vales/vale[rendimiento < 0 or rendimiento > 100 or peso < 0 or not(@numeroSocio = /cooperativa/socios/socio/@numeroSocio)]

Enrique Mora Moral.

Pag: 38/40

5. Mostrar los socios que se encuentran en la lista detrs del socio con nif4 /cooperativa/socios/socio[. >> /cooperativa/socios/socio[nif = "nif4"]] 6. Mostrar los socios que son de la misma poblacin que el socio con nif1. A priori no se conoce la poblacin de este individuo.(0.5) /cooperativa/socios/socio[poblacion = /cooperativa/socios/socio[nif="nif1"]/poblacion]

Ejercicios sobre XQUERY:


1. Generar un pgina WEB con los datos de cada socio, por cada socio mostrar, en una tabla la informacin de sus vales con la fecha, peso, rendimiento y kilos de aceite obtenidos e importe de estos sabiendo que se ha pagado a 1.5 el kilo de aceite en bruto.
<html> <body> { for $socio in doc("cooperativa.xml")/cooperativa/socios/socio let $interna := doc("cooperativa.xml")/cooperativa/vales/vale[@numeroSocio = $socio/@numeroSocio] return <div> <p> Numero: {string($socio/@numeroSocio)} Nombre: {string($socio/nombre)} </p> <p> Numero: {string($socio/@numeroSocio)} Nombre: {string($socio/nombre)} </p> <p> Direccion: {string($socio/direccion)} Poblacion: {string($socio/poblacion)} </p> <table border="3px"> <tr> <td> Numero Parte </td> <td> Fecha</td> <td> Peso </td> <td> Rendimiento </td> <td> Kilos de Aceite </td> <td> Importe </td></tr> {for $vale in $interna return <tr> <td> {string($vale/@numeroVale)} </td> <td> {string($vale/fecha)}</td> <td> {string($vale/peso)} </td> <td> {string($vale/rendimiento)} </td> <td> {string($vale/peso * $vale/rendimiento div 100.0)} </td> <td> {string($vale/peso * $vale/rendimiento div 100.0 * 1.5)} </td> </tr> } <tr> <td colspan="2"> </td> <td> {sum($interna/peso)} </td> <td> {sum($interna/(peso * rendimiento)) div number(sum($interna/peso))} </td> <td>{sum($interna/(peso * rendimiento)) div 100.0} </td> <td>{sum($interna/(peso * rendimiento)) * 1.5 div 100.0} </td> </tr> </table> </div> } </body></html>

2. En cooperatva.xml borrar aquellos socios que no tengan ni portes ni gastos.


for $socio in doc("cooperativa.xml")/cooperativa/socios/socio[not(@numeroSocio = /cooperativa/gastos/gasto/@numeroSocio) and not(@numeroSocio = /cooperativa/vales/vale/@numeroSocio) ] return delete node $socio

Enrique Mora Moral.

Pag: 39/40

3. Generar un documento valesSocios.xml nuevo que contenga los vales agrupados por socios con la siguiente estrucutura: <valesSocios> <socio numeroSocio=> <nif> </nif> <nombre> </nombre> <direccion> </direccion> <poblacion> </poblacion> <telefono> </telefono> <vales> <vale numeroVale = > <fecha> </fecha> <peso> </peso> <rendimiento> <rendimiento> <kilosAceite> </kilosAceite> </vale> <vales> <socios </valesSocios> Solucin:
<valesSocio> {for $socio in doc("cooperativa.xml")/cooperativa/socios/socio let $vales := doc("cooperativa.xml")/cooperativa/vales/vale[@numeroSocio = $socio/@numeroSocio] return <socio numeroSocio="{string($socio/@numeroSocio)}"> {$socio/nif} {$socio/nombre} {$socio/direccion} {$socio/poblacion} {$socio/telefono} <vales> {for $vale in $vales return <vale numeroVale="{string($vale/@numeroVale)}"> {$vale/fecha} {$vale/peso} {$vale/rendimiento} <kilosAceite> {$vale/peso * $vale/rendimiento div 100} </kilosAceite> </vale> } </vales></socio> } </valesSocio>

4. Sobre el documento anterior que se puede llamar sol3.xml mostrar un documento HTML donde aparezca nif, nombre del socio e importe total de sus aceitunas: <html> <body> <table border="3px"> <tr> <td> numeroSocio </td> <td> nif </td> <td> mombre </td> <td> Importe </td> </tr> { for $socio in doc("sol3.xml")/valesSocio/socio let $importe := $socio/sum(vales/vale/kilosAceite) * 1.5 return <tr> <td> {string($socio/@numeroSocio)} </td> <td> {string($socio/nif)} </td> <td> {string($socio/nombre)} </td> <td> {string($importe)} </td> </tr> } </table> </body> </html>

Enrique Mora Moral.

Pag: 40/40

Vous aimerez peut-être aussi