You are on page 1of 38

UNIDAD 9.

Almacenamiento de la información Xquery

Índice de contenido
1.- Sistemas de almacenamiento de la información.........................................................................1 2.- Utilización de XML para almacenamiento de la información....................................................5 3.- Lenguajes de consulta manipulación..........................................................................................6 4.- XQUERY....................................................................................................................................8 5.- Consultas (Flwor a HTML)......................................................................................................18 6.- Actualización (inserción, borrado, modificación)....................................................................30 7.- Exportación de librerías XML..................................................................................................34 8.- Otras funciones o librerías........................................................................................................35

1.- Sistemas de almacenamiento de la información.
Una Base de Datos (BD) es una herramienta que permite organizar los datos que tienen algún tipo de relación entre sí, de manera que son almacenados y utilizados a través de un interfaz de comunicación que facilita su gestión dentro de una entidad u organización. Existen muchas maneras de clasificar los distintos tipos de bases de datos pero podemos resumirlo según la variabilidad de los datos que se almacenen en ellas: • Datos estáticos: Datos que nunca cambiaran en el tiempo (solo lectura). • Datos dinámicos: Datos que pueden modificarse de cualquier manera, a lo largo del tiempo. Salvo contadas excepciones (datos históricos, estadísticas, análisis clínicos que nunca cambiarán desde que se tomaron), las bases de datos que se utilizan hoy en día son dinámicas. Las bases de datos estáticas suelen utilizarse cuando se requiere un alto rendimiento en las consultas, quedando muy penalizadas si tuviera que actualizarse algún dato posteriormente. Los datos que se almacenan en ellas, deben seguir un modelo lógico adecuado para cumplir su función de manera eficiente. Es decir, de alguna manera hay que indicar a la base de datos qué cosas quiere almacenar, enviando una descripción de los datos de interés. Solo así será posible tener un modelo de datos adecuado al problema que se quiera dar solución. Dependiendo de cómo se haya hecho esta descripción de los datos, así cambiarán los procedimientos de acceso, almacenaje y recuperación de los contenidos. Por tanto, dependiendo del modelo de datos utilizado podemos distinguir:

• •

BD Jerárquica: Utilizan árboles para almacenar la información (nodo raíz, nodos padre/hijos, nodos hoja), de manera que la extracción de los datos se realiza mediante un recorrido del árbol y eligiendo la rama por la que debe continuar su búsqueda. Este tipo de estructuras son muy eficientes en las búsquedas pero no pueden reflejar eficientemente la redundancia de datos. BD de Red: Muy parecida a las jerárquicas pero donde un nodo puede tener varios padres simultáneamente (en contraposición de las bases de datos jerárquicas). BD Relacional: Es una base de datos que permite resolver el problema que tenían las bases de datos jerárquicas (las redundancias). Mientras que las jerárquicas la posición del dato en el árbol era importante, en las relacionales es irrelevante. Un conjunto de datos compacto y Pag: 1/38

con sentido propio se almacena en algo llamado tupla. Una tupla no es más que una fila de una tabla en la que se almacena dicha información compacta. El conjunto de tuplas con información semántica 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 información y son las más utilizadas actualmente. BD Transaccional: Utilizan el concepto de transacción (que veremos más adelante) que permite asegurar una serie de características importantes en los sistemas informáticos de hoy en día. Estas características se incluyeron en la mayoría de las bases de datos relacionales de hoy en día. BD Multidimensional: A efectos sería una base de datos Relacional en el que en vez de tener tablas (2D), tendríamos estructuras con N dimensiones para almacenar la información (cubos si fuese 3D). BD Orientadas a Objetos: Difiere de las bases de datos relacionales en que no se almacena la información por tuplas sino por objetos que contienen la información y los métodos que son necesarios para tratarlas. Es llevar la programación orientada a objetos al mundo de las bases de datos generando características como la herencia, la encapsulación 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 común es utilizar un Sistema de Gestión de Bases de Datos o SGBD, que unifiquen las bases de datos entre sí y se mejoren los flujos de distribución de la información en diferentes entornos y/o formatos. Para obtener más información, vea la página http://www.maestrosdelweb.com/principiantes/¿que-son-las-bases-de-datos/. Básicamente se deja de utilizar los almacenes de información de las aplicaciones (los ficheros) para utilizar un interfaz de comunicación único (el SGBD y una BD concreta). Su utilización permite: • Evitar la redundancia de datos que puede producirse por la duplicación de los mismos ficheros de datos utilizados en distintas aplicaciones y/o ubicaciones. • Permiten la abstracción 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 adición de nueva información no planeada en el análisis inicial del sistema obligue a la adaptación de todos los programas informáticos que utilizan esos ficheros. • Evitar que la mala programación en el acceso/modificación/borrado de los datos en un fichero genere problemas de seguridad. Tener una capa de aplicación y una capa de datos distinta facilita la depuración y la trazabilidad de los programas. La abstracción, independencia, consistencia, seguridad y accesibilidad son los objetivos que se buscan en estos sistemas. Además su funcionamiento suele ser muy simple. Se puede resumir en un comentario muy acertado de D. Ángel García Moreno, catedrático de la Universidad Politécnica de Madrid y profesor de la asignatura de Bases de Datos en la Ingeniería Informática: Pag: 2/38

"Mientras que con los métodos clásicos se accedía a la información a través 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 práctica totalidad de los sistemas que quieran almacenar información 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 ubicación desde la cual, las aplicaciones puedan acceder de manera distribuida, concurrente y asegurando la integridad de los mismos. • Permite realizar una correcta política 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 decisión adecuada. Como inconvenientes se pueden enumerar los siguientes: • Un SGBD no es fácilmente administrable. Requiere de personal especializado en administración de sistemas y lenguajes de consultas contra las bases de datos. Una buena administración 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 informática. El personal de nóminas de una empresa, por ejemplo, no tiene porqué aprender un lenguaje de programación de consultas. Requerirá que el sistema le proporcione una interfaz de comunicación 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 pequeño. Siempre habrá que realizar un análisis de los beneficios y los inconvenientes que aportan la integración 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 añadido en los SGBD modernos es el soporte transaccional. Una transacción 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 ejecución de una transacción solo existen dos resultados posibles: • Finalizada con éxito. • No completada (y asegura que no se ha cambiado nada). Veamos un ejemplo de cómo de importante es una transacción. Supongamos que un usuario quiere sacar dinero de un cajero automático. La transacción es "sacar dinero". Para ello se siguen una serie de pasos secuenciales que permiten realizar la transacción con éxito: 1.Validación del usuario (inserción del PIN). 2.Selección del importe a sacar. 3.Anotación en la cuenta bancaria del reintegro. Pag: 3/38

En realidad un SGBD puede verse como un conjunto de actores y componentes que se intercomunican entre sí para hacer más fácil el acceso a los datos. por lo que se podría pensar que es un único bloque funcional. Los anteriores componentes se unen entre sí haciendo que el sistema sea modular y fácil de Pag: 4/38 . Hasta el momento no se ha hablado de cómo está definido un SGBD.4. sus resultados permanecerán inalterables. hecho ad hoc. • Administrador de la Base de datos y Consultas. Si la transacción no ha sido exitosa. acrónimo de: • Atomicidad (Atomicity): Es la propiedad que asegura que una transacción no se ha quedado a medias. Esto implica que dos transacciones que trabajen sobre el mismo conjunto de información no puede generar información inconsistente o error alguno en el sistema. Normalmente son dispositivos con capacidades de redundancia y con alta disponibilidad para soportar cualquier contingencia que surja durante su funcionamiento. Estos componentes son: • El Hardware: Dispositivos físicos donde residen todos los demás componentes del SGBD. el usuario tendría anotada en su cuenta bancaria un reintegro que nunca ha sido entregado al usuario (paso 4). ni que tampoco se ha anotado el reintegro en la cuenta bancario del usuario (incluso aunque haya habido un corte en el flujo eléctrico y estuviese la transacción en el paso 3). haciéndoles transparente el acceso a los datos. • Aislamiento (Isolation): Una transacción no puede afectar a otra en el transcurso de su ejecución. asegura que ni el dinero ha salido por el cajero. si es ejecutada de manera exitosa. • El Software: Aplicación que permite abstraerse de las características físicas del hardware y que permite hacer al SGBD ser independiente de la plataforma hardware sobre la que se ejecuta. • Durabilidad (Durability): Una vez realizada la transacción. • Consistencia (Consistency): Una vez se ha determinado que la transacción ha sido exitosa. • Usuario Final. dependerá del software SGBD que se vaya a utilizar pero genéricamente podemos identificar los siguientes roles: • Administrador del Sistema informático. independientemente del Hardware o Software utilizado. asegura que los pasos del 1 al 4 se han seguido en ese orden y que todo ha salido bien. • Los Usuarios: Actores a los que se les permite interactuar con el SGBD. Es decir. Obviamente el usuario se enfadaría y reclamaría. • Los Datos: Información almacenada dentro del recinto físico (hardware) y administrada por el software. su nombre técnico en un SGBD se denomina características ACID. Si está en el paso número 3 y después hubiera un corte en el suministro eléctrico. Una transacción. al no ser exitosa la transacción es como si nunca hubiese pasado. O se ha ejecutado completamente o ninguna de las acciones intermedias ha sido llevada a cabo en la base de datos. independientemente de si surgen problemas en el sistema. Esto que. debe quedar reflejados sus resultados en la base de datos dejando totalmente consistente e integra la base de datos. explicado con un ejemplo es tan simple. En relación a los usuarios. Esto no quiere decir que una transacción posterior no pueda modificar los datos anteriormente modificados (sí podría pero no de manera concurrente con otra transacción). para resolver un problema de almacenamiento de datos concreto.Expedir tique y el dinero solicitado al usuario.

• El disco duro. • La cinta mágnetica. lo que el almacenamiento de datos puede no ser un problema. incluso aquellos procedentes de fuentes no Pag: 5/38 . Pero lo que debe ser fundamental es el dimensionamiento del almacén de datos para que no se quede pequeño.Utilización de XML para almacenamiento de la información.. su estructura se simplifica como consecuencia de los principios de orden y jerarquía que incorpora todo documento XML. • Los pendrives. Cualquiera que sean los datos que se almacenen. Los disquetes. si se hace en formato XML. 2. Simplemente sustituyendo un disco por otro de mayores dimensiones el problema se resuelve y además es seguro que será más rápido que el antiguo (lo que aceleran las transferencias de información). La tarjeta perforada.usar/administrar. • Los discos duros en estado sólido. • El CD-ROM / DVD. • Las tarjetas de memoria. Únicamente queda por hablar del sistema hardware que se debe utilizar para llevar a cabo la instalación de un SGBD. Es claro que los discos duros actuales están alcanzando tamaños impensables. el almacenamiento de la información ha pasado por muchas etapas: • El cableado físico. Ello permite representar muchas clases de datos. Todo dependerá del grado de concurrencia de accesos y la cantidad de datos a almacenar los que determinarán las características físicas del hardware. Para pequeñas y medianas empresas cualquier servidor relativamente moderno puede servir. Desde la máquina analítica de Charles Babbage hasta los netbook de hoy en día.

etc. d) Densidad: los datos relacionales son densos (cada columna un valor) y los inexistentes se declaran como tales (con null). sino que además se obtiene un fragmento de XML como resultado de ello. Mientras que en Informática consultar es acceder a datos ya almacenados sin que durante el proceso se cree otra cosa que no sea el propio resultado de la búsqueda. en cambio los datos en XML son dispersos. 3. Vamos a reseñar las diferencias existentes entre datos XML y datos relacionales: a) Metadatos: los datos relacionales presentan estructuras regulares y homogéneas (cada fila tiene las mismas columnas con los mismos nombres y tipos) lo que permite usar metadatos sin ningún problema. Ante las consideraciones anteriores. b) Anidamiento: los documentos XML contienen distintos niveles de anidamiento.) con estructuras diferentes que deben describirse caso a caso.Lenguajes de consulta manipulación. W3C decidió que las consultas en XML debían ser objeto de un nuevo lenguaje. que se llamó XQuery. los requisitos puestos por W3C a XQuery son: Clausura del modelo: toda consulta y todo resultado debe obedecer a un mismo modelo de datos. En consecuencia. mientras que los datos relacionales son «planos» al estar organizados a partir de tablas.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. cosa que difiere de SQL. que son irregulares e impredecibles. Compatibilidad con los Esquemas: ello supone disponer tanto de un conjunto de tipos primitivos como de la posibilidad de definir nuevos tipos. que a su vez pueden servir de intermediarios para procesar una expresión de mayor nivel. e) Mecanismo de consulta: en XML el resultado de una consulta consiste inevitablemente en una secuencia heterogénea de elementos. «los objetos que están después de A y antes de X». etc. Como consecuencia XML es más libre que el modelo relacional a la hora de enfrentarse con datos faltantes. mientras en XML los datos son heterogéneos e irregulares (página web. donde toda expresión dentro de una consulta devuelve una tabla. con un mecanismo que además Pag: 6/38 . atributos y valores primitivos.. c) Jerarquía: en XML existe una jerarquía y un orden intrínseco que no se da en la estructura relacional. esto es: «ser cerrado respecto al modelo de datos Xquery». en el caso de XML. 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. ello se refleja en la forma de trabajar de XPath («el quinto objeto rojo». y la información que no existe sencillamente carece de elemento. se trata de requisitos que en cambio son irrelevante en el caso relacional con el uso de SQL. Por ello. una consulta XQuery tiene como entrada y salida sendos documentos XML. de forma que estos metadatos se acaban describiendo en el propio documento. que es la gran referencia en Informática para la consulta de datos. las posibilidades que conocemos existen con el uso de SQL en el modelo relacional. que conducen a la conclusión 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.) cuando este orden y esta jerarquía carece de relevancia en el modelo relacional. con lo que éste no es sólo un lenguaje de consulta que opera sobre documentos (para ser más preciso. capítulo de libro. no sólo se consulta en el concepto habitual. sobre instancias de un modelo de datos XML) sino que también genera documentos XML a demanda de la consulta correspondiente.

una DTD o incluso carecer de cualquier descripción. deben poder combinarse entre ellas con la máxima generalidad. Semántica: no deben existir grandes restricciones semánticas a la hora de proporcionar el resultado de una consulta. los operadores aritméticos que se utilicen (como +) cuando se aplican a un elemento. e incluso con datos que carezcan de cualquier tipado. donde los tipos de entrada y salida se descubran en tiempo de ejecución. Generalidad: el lenguaje debe poder aplicarse tanto en entornos que usen tipos de datos muy estrictos y bien especificados. mientras que por su parte los operadores de comparación (como =) aplicados a una secuencia de valores.) en XQuery se optimiza el análisis y el proceso de detección de errores. sea un Esquema. uno o muchos ítems. como en otros. El cumplimiento de lo anterior conduce inevitablemente a una semántica compleja. Esta exigencia es debida al hecho de que la obtención de un «valor» en estas consultas puede consistir en ninguno. XQuery debe poder trabajar con documentos descritos de formas muy distintas. se pueden identificar las partes de un documento y con ello recuperar la información deseada. automáticamente extraen su valor numérico. Completitud: aunque sin conseguir una potencia expresiva comparable a la completitud del modelo relaciona]. decidiéndose automáticamente qué errores se permiten y cuáles no. iteran buscando los valores que satisfagan la comparación. Pag: 7/38 . y al objeto de simplificarla en XQuery se definen operadores con operaciones implícitas. atributos o valores primitivos. que el resultado de cualquier expresión se debe poder usar como operando de otra. Análisis estático: asumiendo que el proceso de consulta tiene dos fases: análisis y evaluación (parecido a la compilación y ejecución de un programa. Compatibilidad con XPath: al basarse en este lenguaje de localización de la familia XML. que a su vez pueden ser elementos. de forma automática. XQuery debe ser capaz de obtener un documento XML construido a partir de documentos diferentes. por lo que en la práctica las consultas XQuery tienden a ajustarse a las tareas que puedan interaccionar con aquellas cosas que ya están almacenadas siguiendo la sintaxis de XML. siempre usando para ello el cálculo de predicados de primer orden y las funciones recursivas. lo que hace que sea necesario que todo operador XQuery tenga bien definidas todas las posibilidades que puedan aparecer. Así por ejemplo. Ello significa en la práctica. Como puede verse se trata de trabajar con los mayores grados de libertad posible en la semántica a la hora de efectuar una consulta. En otras palabras.incorpore el correspondiente proceso de validación. Posibilidad de Composición: la totalidad de las distintas expresiones basadas en XPath sean condicionales o cualquieras otras. De estos requisitos se constata que el objetivo de XQuery se centra mucho más en la recuperación de información que en la actualización de documentos ya existentes.

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

Definiciones básicas Un literal es la clase más simple de expresión XQuery. Una forma de dar valores a una variable es por medio de una expresión let que asocia una o varias variables y luego evalúa la correspondiente expresión interna.xml “: Pag: 9/38 . y xs:double y los tipo cadena se delimitan por comillas pudiendo contener referencias a entidades predefinidas. El prólogo consta de una serie de declaraciones que definen el entorno para el procesado del cuerpo. Para identificar los datos de entrada existen dos funciones básicas: doc() que devuelve un documento completo identificándolo con una URI. Por tanto. Un constructor es una función que crea un valor de un tipo particular a partir de una cadena que contiene la representación léxica del tipo deseado. Esquemas o funciones. donde los tipos numéricos son xs:integer. Se habla de un error dinámico si las funciones doc() y collection() no localizan lo especificado en ellas.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 extraído del fichero anterior. 4.Donde puede utilizar constantes y valores extraídos con XQUERY para montar una estructura fija. El prólogo se usa cuando el cuerpo depende de los espacios de nombres. por ejemplo: string($persona/nif) Los distintos tipos de valores atómicos se crean llamando a un constructor. o bien referenciando alguna parte de un contexto externo. Una transformación es el paso de una instancia del modelo de datos a otra instancia de este modelo.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). que consta de una expresión cuyo valor proporciona el resultado de la consulta. xs:decimal. Una variable en XQuery es un nombre que empieza con el signo dólar ($a) o con el mismo nombre que una etiqueta ($nif) que se asocia a un valor y que se usa dentro en una expresión para representarlo. En consecuencia sus valores se corresponden con los tipos simples de Esquema. que en general tiene el mismo nombre que el tipo que construye. El resultado de la anterior consulta devuelve: <?xml version="1.1. Como ejemplo de la forma de trabajar. por ejemplo: doc(“personas. sea el documento “personas. dejando abierto tanto el origen de los datos de entrada como la forma corno se envía el resultado a la aplicación que haya invocado esta transformación. y cuando ello ocurre la consulta depende en gran medida de lo especificado en él. y representa un valor atómico. collection. una consulta puede tener su entrada bien por medio de doc. Una consulta consta de dos partes: prólogo (querv prolog) y cuerpo (querv body).

cosa que podemos hacer mediante: <resumenPersonas> { for $persona in doc("personas.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 cómo obtener el sumario con el nif y nombre de cada persona.<?xml version="1.{string($persona/nombre)} </resumenPersona> Pag: 10/38 .xml")/personas/persona return <resumenPersona> { string($persona/nif)} --.

0" encoding="UTF-8"?> <resumenPersonas> <resumenPersona>nif1 --. Pag: 11/38 . de poder detectar posibles errores antes de que la consulta se ejecute del todo. y por ello las expresiones deben estar bien definidas para que se esté en condiciones de poder evaluar cualquier estructura. Como conclusión. Por 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. XQuery se especificó para trabajar con datos poco o muy tipados.nombre4</resumenPersona> <resumenPersona>nif5 --.nombre1</resumenPersona> <resumenPersona>nif2 --. como sería el caso de un Sistema de Gestión de Base de Datos relacional. con ello. a pesar de ello. reténgase que para encarar esta variedad de situaciones. recordando los requisitos puestos a XQuery.nombre2</resumenPersona> <resumenPersona>nif3 --. éste debe estar en condiciones de poder procesar documentos tan distintos corno: • • • Los tipados (uso de tipos xs.} </resumenPersonas> Generando el siguiente resultado <?xml version="1. Si el documento XML manejado obedece sólo a una DTD o incluso si carece de cualquier esquema. xsd) con Esquemas o Relax NG. Los usados con una visión procedente de otro sistema no XML. siendo su sistema de tipos uno de sus aspectos más útiles.2. siendo capaz. terminando con /personas/persona que selecciona cualquier elemento Capitulo del documento objeto de la consulta. lo que evita un gran número de errores. Tipos de datos en Xquery Puesto que un documento XML puede contener una gran variedad de información. la sentencia return define la salida para cada nodo que aparece en la secuencia definida por la variable $persona. 4. XQuery permite escribir consultas con muy poca información sobre tipos.nombre5</resumenPersona> <resumenPersona>nif6 --. Obsérvese que las fuentes de datos pueden tener estructuras muy complejas. Ello es factible gracias a la capacidad de XQuery para obtener y utilizar la información de tipos en tiempo de ejecución. Por su parte. lo que supone contar con un lenguaje de consulta con datos estáticos fuertemente tipados.nombre6</resumenPersona> </resumenPersonas> donde se observa cómo 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.nombre3</resumenPersona> <resumenPersona>nif4 --. un lenguaje de consulta debe evitar todas las suposiciones previas que puedan terminar generando conflictos con los datos que se vayan a encontrar. eclécticos e inusuales que existen. Por ello. Los gobernados por otros lenguajes de esquema como DTDs.

en lo que resta de capítulo nos enfrentaremos a tres apartados. los tipos importados para la consulta desde un Esquema específico. que pueden ser bien tipos predefinidos.3. Capacidades de XQuery Al objeto de resumir las potencialidades de XQuery. y los importados para una consulta desde un Esquema concreto. permitiendo con ello que las consultas accedan a ellos. La combinación y reestructuración de los documentos XML obtenidos. cuando XQuery se enfrenta con tipos de datos derivados de Esquemas XML. Hagamos notar que al ser secuencias los valores habituales en XQuery. cosa que unas veces puede hacerse antes de que se ejecute la consulta y otras sólo duran-te la ejecución. cuando se evalúe la expresión correspondiente. y el modelo de datos preserva esta información de tipos. sea aconsejable proceder a su importación. los tipos usados para describirlos se llaman tipos secuencia.. Lo dicho no obsta para que en el caso de que la consulta utilice una lógica relacionada con el significado de un Esquema. y por ello ser usados en cualquier consulta. y por otro. accesibles por cualquier consulta. Así.4. Es importante hacer notar que con el mecanismo XQuery básico. Sistema de tipos: XQuery básico Puesto que el sistema de tipos de datos de XQuery se basa en Esquemas. los tipos predefinidos accesibles en toda consulta. 4. etc. Como se ha dicho.los tipos son muy reducidos: documento. Pag: 12/38 . y en con-secuencia debe estar en condiciones de manejar. la posibilidad de utilizar un tipado estático que permita que una consulta pueda contrastarse con los Esquemas importados. se pueden usar sin problemas los correspondientes tipos simples que se encuentren presentes en los datos del documento. o bien estar definidos en un Esquema. a las implementaciones XQuery se les requiere que detecten errores de tipo. con lo que el documento incorpora poca información referida a tipos. elemento. aunque una consulta no importe Esquema alguno. y por otro. los cuales deben importarse previamente. 4. cuya razón de ser ya hemos introducido: • • El manejo de los árboles de XQuery. una consulta no necesita importar ningún Esquema para poder utilizar tipos predefinidos. cosa que para hacerse debe ser tenido en cuenta por la aplicación que vaya a generar la consulta. ya que están contenidos en el propio documento. Se llama XQuery Básico al mecanismo que admite por un lado la importación de Esquemas para hacerlos accesible a la consulta. y por ello las consultas se hacen confiando en un conjunto de reglas. debe distinguir mucho más. de tal manera que durante el proceso de ejecución se pueda inferir el tipo apropiado para poder obtener el valor buscado. En cambio. IDREF. ID. de forma que se puedan localizar los posibles errores antes de acceder a los datos. por un lado. Un procesador dotado de tipado estático por tanto puede detectar determina-dos tipos de errores mediante la simple comparación de la consulta con el Esquema importado. A la primera posibilidad se le llama tipado estático y se efectúa usando simultáneamente la información importada y la propia de la consulta. Esta flexibilidad de XQuery debe ser apreciada debidamente. hay que distinguir dos conjuntos de tipos: los predefinidos. lo que significa que no se requiere acceder a los datos para encontrar tales errores.

0" encoding="UTF-8"?> <!ELEMENT personas (persona)* > <!ELEMENT persona (nif. éstas se definen en el prólogo de la consulta. Son ejemplo de su funcionamiento: • • doc("personas. de forma que una vez declaradas son accesibles en cualquier punto. Recorrer y construir árboles en XQuery Para presentar las expresiones y operaciones básicas que permiten recorrer y construir árboles con XQuery. En el Pag: 13/38 . usaremos el marco de las distintas tareas a llevar a cabo: a)La localización de nodos utilizando expresiones basadas en trayectos XPath. sus expresiones deben poder localizar nodos empezando por determinar el documento en el que efectuar la búsqueda. En el caso de que en este proceso se vayan a necesitar variables. nombre. con /personas se selecciona este elemento y con /personas/persona se obtienen estos elementos dentro de personas.1 de esta unidad. 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. c)La extracción de tipos.5.xml")/personas/persona abre el documento personas.• Los cuantificadores. tiene sentido definir una variable. Como ejemplo de referencia de este proceso usaremos el documento personas. Localización de nodos en estructuras XML Para que XQuery cumpla su objetivo. Así. si los nombres de las personas en personas.xml van a usarse varias veces en una consulta.xml") /personas/persona[3] devuelve la tercera persona de mi lista En la línea de las expresiones XPath.xml obteniendo su nodo documento. Por ejemplo: doc("personas.xml incluido en el apartado 4. poblacion. tal como: $nombre Los predicados XPath como métodos para filtrar secuencias de nodos se generalizan en XQuery de forma que el valor de una expresión siempre sea una secuencia heterogénea de nodos y valores atómicos. b)La obtención de estructuras XML usando constructores. direccion. Con la siguiente estructura: <?xml version="1. una expresión en XQuery puede empezar con / o //.xml") /personas/persona[nif="nif1"] que devuelve sólo aquellas personas que tengan como nif el valor “nif1” doc("personas. operadores y funciones propias de XQuery.

Igual que en XPath.xml")//persona[1]/nombre </eg> <p> Este es el resultado de la consulta anterior.</p> Pag: 14/38 .45</peso> es un elemento de nombre peso que contiene un literal. cosa que se hace mediante el uso de constructores. mientras que el significado del operador //. esta capacidad de construir nuevos objetos XML es una de las funcionalidades más importantes de XQuery.primer caso la búsqueda se inicia en el nodo raíz. por ejemplo: doc("personas. las «wildcards» permiten que las consultas seleccionen sin especificar sus nombres completos. se debe crear el resultado que satisface la consulta. en XML sólo es un carácter. hasta crear un documento completo. esté o no en el espacio de nombres.85}</peso> es un elemento construido cuyo contenido se calcula evaluando una expresión. mientras que: <peso>{$peso * 0. por ejemplo: • • • doc ( "personas. La tecnología es semejante a la usada por PHP contra HTML a la hora de generar documentos dinámicos. Así: <peso>123. ya que las expresiones XQuery soportan espacios de nombres.xml" ) //nombre cualquier nombre del sistema.85. xml" ) / / @edad elementos que tenga definido el atributo edad. Incluso se repiten las constantes del estilo <peso> cuando utilizamos bucles FOR. si en ella hubiera algo que no correspondiera a uno de estos nodos aparecerá un error de tipo.xml")//persona[4]/* obtiene los elementos/etiquetas una a una de la cuarta persona. La sintaxis para ello se basa en la evaluación de una expresión que aparece entre llaves y que obviamente no tiene el mismo significado que en la notación XML. por ejemplo: <ejemplo> <p> Esta es una consulta </p> <eg> doc("personas. es dar acceso a todos los atributos y descendientes de los nodos que aparecen en su izquierda en el documento considerado. ya que mientras en XQuery el símbolo { es el inicio de una expresión a evaluar. la consulta se inicia creando un nodo documento que empieza siendo vacío y que acaba rellenándose con el resultado correspondiente. 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. Una vez proporcionado explícitamente un constructor por medio de { }. Las expresiones delimitadas por { } siempre están encargadas de evaluar y crear contenidos de elementos o atributos. en términos del modelo de datos. Hagamos notar que debido a que durante el proceso de evaluación de toda expresión XQuery siempre se devuelven nodos del documento señalado. doc (" libros . lo que permite distinguir nombres procedentes de vocabularios diferentes. Construcción de estructuras XML Una vez localizados los nodos en un documento.

<eg>{ doc("personas. los tipos de datos permiten comprobar la corrección tanto de la propia consulta como de las operaciones a los que se va a someter los datos de la respuesta. 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. de forma que durante el correspondiente proceso de validación los nodos elemento y atributo puedan adquirir sus notaciones de tipo correspondientes. en el prólogo de toda consulta deben figurar explícitamente los Esquemas que se van a importar.xml")/persona/persona/telefono )} </media> calcula el valor medio de la etiqueta telefono en nuestro ejemplo. La consecuencia a retener es que la falta de definición de tipos no impide que se puedan efectuar consultas con XQuery. todos los nodos elemento tienen por defecto como notación tipo xs:anyType.xml")//persona[1]/nombre </eg> <p> Este es el resultado de la consulta anterior.0" encoding="UTF-8"?> <ejemplo> <p> Esta es una consulta </p> <eg> doc("personas. creando con ello constructores sucesivamente más complejos que van anidando elementos y atributos.xml")//persona[1]/nombre }</eg> </ejemplo> produce el documento: <?xml version="1. Las expresiones incluidas en los constructores de elementos permiten crear nuevos valores XML reestructurando los existentes. por ejemplo: <media> {avg( doc("personas. aunque no hayamos usado un Pag: 15/38 . mientras que el segundo es sustituido por el resultado de evaluar la expresión anterior. identificándolos por su espacio de nombres.</p> <eg> <nombre>nombre1</nombre> </eg> </ejemplo> El primer “doc("personas. Recordemos que en el caso de que no se usen Esquemas. Extracción de tipos En un lenguaje de búsqueda.0" encoding="UTF-8"?> <numero>6</numero> Debe hacerse notar. aunque no mostremos ningún ejemplo. en base a ello.xml")/personas/persona)} </numero> se obtiene el documento: <?xml version="1.xml")//persona[1]/nombre “ se comporta como una constante. Por ello. la posibilidad existente de enlazar constructores de forma sucesiva. como vamos a contar el numero de personas de nuestro fichero: <numero> {count(doc("personas.

Para que ello sea posible.0" encoding="UTF-8"?> <resultado>4</resultado> En este proceso se esta evaluando al tirón el código XML que se encuentra dentro de la función data.xml")/personas/personas/[nombre='nombre1'] donde siendo nombre un elemento y `nombre1' una cadena. la media se calcularía usando números decimales. en XQuery existe una operación básica llamada extracción de tipo. <?xml version="1.xml")//persona Pag: 16/38 . obteniendo que es una cadena. Obviamente. Así. cuyo significado es evidente. En línea con lo anterior. según el tipado que incorpore el operador (por simplicidad adelantamos el uso de dos de ellos. hay que preguntarse cómo se interpretaría si $b adoptara las distintas posibilidades existentes (por ejemplo que fuera una secuencia vacía. o una secuencia de cinco nodos. Consecuencia de lo anterior es la necesidad de conocer la forma como XQuery trata las distintas casuísticas que pueden aparecer durante el procesado de un documento. 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. donde el precio se representaría mucho mejor por un decimal. Lo normal es que se evalúe una variable que contiene una etiqueta.). Este sería el caso de la consulta: for $b in doc("personas. Este tipo de cuestiones es básico que puedan resolverse. y el elemento telefono no esta bien tipado. Para hacer frente a esta necesidad. se pueda asumir que pueden ser iguales. Esta conversión implícita siendo muy útil cuando se trabaja con datos no tipados puede no ser óptima. o un dato de caracteres sin tipar o un elemento. por ejemplo. etc.Esquema o Relax sino un DTD. Este proceso de extracción de tipo permite que tengan sentido expresiones como: doc("personas. se trata como una cadena y en consecuencia sólo puede compararse con otra cadena. automáticamente cada valor de telefono se convierte a doble precisión y se calcula la media requerida. adelantemos que XQuery incorpora la función data() que extrae directamente el tipo del valor correspondiente. La clave reside en que el operador = extrae el tipo de valor del elemento. de evidente significado eq y gt): • Si se carece de tipo. si en el proceso de consulta existiese un Esquema que declarase telefono un campo peso como decimal. sin tener que preocuparse del tipo de dato concreto. si nos encontramos con una expresión como: 1 * $b. cuando avg() requiere un argumento numérico. como en el caso del ejemplo que se acaba de ver. lo que obliga a que casos como éstos deben quedar bien definidos a lo largo del proceso de consulta. lo que permite a XQuery poderla comparar con 'nombre1' y tomar la decisión que corresponda. Veamos lo que ocurre en el caso del elemento precio. debido a la propia flexibilidad del XML.

no se pueden usar los tipos simples de los Esquemas. adelantándonos a secciones siguientes. for $telefono in doc("personas.xml")//persona where xs:decimal($b/telefono) gt 33. El hecho de que los Esquemas tengan tipos predefinidos permite usarlos para escribir funciones similares a las de los lenguajes de programación convencionales. y se fuerza a la consulta a tenerlos que interpretar antes de compararlos. por ejemplo: declare function local:reverse($items) { let $count := count($items) for $i in 0 to $count return $items[$count .where $b/poblacion eq "pueblo1" return $b/nombre • Si los datos dependen de una DTD. una función que eleva al cuadrado los telefonos: declare function local:cuadrado ($p as xs:integer) as xs:integer {$p * $p}. con la única excepción de que sean cadenas o que efectivamente contengan los tipos adecuados.xml")//telefono return <cuadrado> {local:cuadrado ($telefono)} </cuadrado> de forma que la expresión $e/. Como norma general en XQuery. es necesario pasar telefono a decimal: for $b in doc("personas.$i] }.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. consideremos el caso de una función que devuelva una secuencia de ítems en el orden inverso al existente en el documento. la posibilidad de trabajar con datos poco tipados en ocasiones es una ventaja no despreciable que el buen uso de XQuery puede explotar. let $persona := doc("personas.. ni el tipo que será devuelto. del documento instancia será cierto cuando se evalúe para este nodo. Por ello en la siguiente consulta. con lo que el telefono no tiene tipo. nada de lo anterior es necesario. A pesar de lo dicho.xml")/personas/persona return local:reverse($persona) Pag: 17/38 . Como ejemplo. Como ejemplo. aprovechando las estructuras de XML. ya que es razonable que esta función pueda aplicarse a cualquier secuencia de ítems. una situación en la que parece razonable que no se especifique ni el tipo del parámetro de la función. los datos objeto de consulta se interpretan como datos tipados.00 return $b/nombre Devolviendo: <?xml version="1.

Cláusulas FLWOR Se llama tupla a una combinación de variables asociadas a una expresión FLWOR formada por las cláusulas for o/y let. ni para los parámetros ni para el resultado. ya que invariablemente algo se devuelve como consecuencia de una consulta. seguidas por where o/y order y obligatoriamente por return. 2. 3) para construir una sucesión de enteros. Para efectuar estas tareas existen una serie de expresiones. LET. llamadas FLWOR (de las iniciales de FOR.el operador to genera sucesiones de persona girandolas con la función reverse. por ejemplo: for $b in doc("personas. asociando la variable $b a cada persona para crear una serie de tuplas. El resultado que se obtiene es: <?xml version="1. 2. Así en: for $i in (1. WHERE. Al no especificar ningún tipo. dando como resultado: <?xml version="1. 3) return <tupla><i>{ $i }</i></tupla> se crea un elemento tupla donde $i se asocia a (1. existiendo distintas combinaciones posibles para ellas.0" encoding="UTF-8"?> <nombre>nombre1</nombre> Las cláusulas for y let Toda expresión FLWOR incorpora al menos una de estas cláusulas. ORDER y RETURN que se pronuncia como en inglés «flower») que juegan un papel similar al de las instrucciones SELECT-FROM-WHERE de SQL al asociar valores a variables para poder obtener resultados. En este ejemplo where comprueba si $b/@edad es igual a 25 de forma que return se evalúa para cada tupla que satisfaga la condición. podría usarse para devolver una secuencia de cualquier otro tipo de datos..Consultas (Flwor a HTML) En XQuery las consultas combinan información de una o más fuentes por lo que necesariamente ésta debe reestructurarse para obtener el resultado deseado.0" encoding="UTF-8"?> <tupla> Pag: 18/38 .xml")/personas/persona where $b/@edad = 25 return $b/nombre devuelve las personas cuya edad es 25. 5.

donde la variable $i está limitada a la secuencia entera de enteros: let $i := (1. las variables asociadas a let se añaden a las tupías generadas por las cláusulas for. 3) return <tupla> {$i} </tupla> Con el siguiente resultado: <?xml version="1.xml")/facturacion/facturas/factura let $c3 := doc("facturacion.0" encoding="UTF-8"?> <tupla>1 2 3</tupla> Cuando let se usa en combinación con una o más cláusulas for. 2.la variable y es global dentro de todo el buble mostrando los valores de forma correcta permite mezclas con factura recomendación --> <tr> <td> {$c3/nif} </td> <td> {$c3/nombre} </td> </tr> <tr> <td> {$factura/nif} </td> <td> {$c3/nombre} </td> </tr> <!-. <html> <body> {for $factura in doc("facturacion. 2. 3). 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 relación entre let y return: (: cada return debe completar un código XML valido :) (: se puede engañar devolviendo en una función una lista de nodos :) declare function local:clientes ($p1) { let $cliente := doc("facturacion.xml")/facturacion/clientes/cliente[nif = $p1] return (<td> {$cliente/nif} </td> . 3) let $j := (1. <td> {$cliente/nombre} </td>)}.engaño con una función que devuelve una lista de nodos de dificil utilidad--> Pag: 19/38 . el resultado es una única tupla. 2. Si en el anterior se usa let en lugar de for. por ejemplo: for Si in (1.<i>1</i> </tupla> <tupla> <i>2</i> </tupla> <tupla> <i>3</i> </tupla> En cambio la cláusula let asocia una variable al resultado global de una expresión y si no existen en ella ninguna cláusula for.xml")/facturacion/clientes/cliente[nif = $factura/nif] return <table> <tr> <td> {string($factura/numero)} </td> <td> {string($factura/fecha)} </td></tr> <!-. se crea una sola tupla. esto es: let $i := (1.

Quedando: for $p in doc("personas.<tr> {local:clientes (string($factura/nif))} </tr> <!-. $p/@edad. con el objeto de poder cambiar el orden del resultado. donde la cláusula where puede contener cualquier expresión que se evalúe a un valor booleano. Podemos consultar las personas que no incluyen el atributo edad.xml")/personas/persona where $p/@edad > 25 return $p d ando como resultado. ningún elemento para nuestro caso.xml")/personas/persona where not($p/@edad ) return $p Aunque su análogo en SQL WHERE sólo comprueba valores simples. esta restricción no se da en XQuery. <td> {$c2/nombre} </td> ) } </tr> </table>} </body> </html> La cláusula where Esta cláusula elimina las tupías que no satisfacen una determinada condición.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. Aunque sea una expresión compleja sobre los sug-elementos de un objeto. $p/poblacion descending return $p Pag: 20/38 .Declaración de la variable donde se cierra y se abre una elemento dentro del bucle en casos concretos.xml")/facturacion/clientes/cliente[nif = $factura/nif] return ( <td> {$c2/nif} </td> . para ordenar alfabéticamente las personas por nombre en orden descendente se puede escribir: for $p in doc("personas.xml")/personas/persona order by $p/nombre descending. La cláusula order Esta cláusula ordena las tupías antes de evaluar return. for $p in doc("personas. funciona como una función --> <tr> {let $c2 := doc("facturacion. Así. de forma que return sólo se evalúa para aquellas personas cuya edad supere los 25 años.

xml")/personas/persona return <persona> { $p/nif. $p/nombre } <direccion> {concat(data($p/direccion). $p/nombre } </persona> } </personas> el resultado que se obtiene es: <?xml version="1. data($p/poblacion))} </direccion></persona> } </personas> Pag: 21/38 .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 cláusula return.xml")/personas/persona return <persona> { $p/nif. Por ejemplo. Así por ejemplo. la tarea de insertar un elemento dirección que mezcle los campos dirección y población en una única etiqueta: <personas> {for $p in doc("personas.La cláusula return Esta cláusula está en toda expresión FLWOR y también es común en los elementos constructores. 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.

")")} </direccion></persona> } </personas> Expresiones condicionales En XQuery se utilizan expresiones condicionales de la misma forma que en otros lenguajes.la consulta tiene como resultado: <?xml version="1. data($p/poblacion). " (". Comenzamos modificando nuestro fichero de personas con la siguiente estructura: <?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 dirección de población o incluso meter la población entre paréntesis basta con: <personas> {for $p in doc("personas. $p/nombre } <direccion> {concat(data($p/direccion). por lo que aparece en XQuery tanto la cláusula if como then y else.xml")/personas/persona return <persona> { $p/nif.0" encoding="UTF-8"?> Pag: 22/38 .

xsl"?> <!DOCTYPE personas SYSTEM "file:/media/Datos/Curso11-12/proyecto1/personas.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="hoja1.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> Pag: 23/38 . poblacion. ajustando los gastos de estas personas: <?xml version="1. direccion.<!ELEMENT personas (persona)* > <!ELEMENT persona (nif. valor) > <!ELEMENT fecha (#PCDATA) > <!ELEMENT valor (#PCDATA)> <!ATTLIST persona edad CDATA #IMPLIED > <!ATTLIST persona codigo ID #IMPLIED > Sobre esta estructura modificamos nuestros datos.gastos) > <!ELEMENT nif (#PCDATA) > <!ELEMENT nombre (#PCDATA) > <!ELEMENT direccion (#PCDATA) > <!ELEMENT poblacion (#PCDATA) > <!ELEMENT telefono (#PCDATA) > <!ELEMENT gastos (gasto)* > <!ELEMENT gasto (fecha. telefono. nombre.

</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> </personas> Como ejemplo podemos obtener consultas complejas. for $p in doc("personas. como personas que tengan más de dos gastos.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> Pag: 24/38 .xml")/personas/persona where $p/gastos/count(gasto) >= 2 return $p como resultado sale: <?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.<fecha>2012-02-01</fecha> <valor>200</valor> </gasto> </gastos> </persona> No es una sentencia condicional. El resultado que se obtiene es: <?xml version="1. 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> Pag: 25/38 . (>= 2): <personas> { for $p in doc("personas. pero aprovechando el count anterior puedo añadir una etiqueta <numeroDeGastos> al nif y al nombre de las personas que tengan dos gastos o más. $p/nombre} { if ($p/gastos/count(gasto) >= 2) then <numeroDeGastos> {$p/gastos/count(gasto)} </numeroDeGastos> else () } </persona> } </personas> donde la secuencia vacía () se usa para especificar que una cláusula no devuelve nada.xml")/personas/persona return <persona> {$p/nif.

El el primer caso busca la existencia de un gasto individual superior a 400. El resultado obtenido es la quinta persona con que presenta un gasto de 500: <?xml version="1. éste es el ámbito respectivo de los cuantificadores existencial y universal. en el segundo busca que el total de sus gasto supere a 400. Cuantificadores Para las consultas basadas en una condición resulta básico determinar tanto si existe al menos un ítem que la satisfaga.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. Por su parte. En este caso sería algo parecido a: for $p in doc("personas. podemos seleccionar aquellas personas en las que cada uno de sus gastos supera los 200.xml")/personas/persona where every $g in $p/gastos/gasto satisfies ($g/valor > 200) Pag: 26/38 . pero la consulta anterior es distinta a la que utiliza la clausula exist. un cuantificador universal tiene la función de comprobar si todos los nodos de una determinada secuencia satisfacen la condición objeto de la consulta. for $p in doc("personas. veamos de forma más sistemática las piezas con las que se elaboran las consultas Xquery. el cuantificador existencial some incluido en la cláusula where se encarga de comprobar si existe al menos un gasto de una persona superior a 400. como saber si todos los ítems involucrados en ella lo hacen. Consideremos la consulta: for $p in doc("personas. Por ejemplo.Operar en XQuery Aunque ya han sido utilizadas en algunos casos.xml")/personas/persona where some $g in $p/gastos/gasto satisfies ($g/valor > 400) return $p en ella.xml")/personas/persona where sum ($p/gastos/gasto/valor) > 400 return $p En este caso devuelve el mismo valor.

return $p Obteniéndose 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> Pag: 27/38 .

si no hay ningún gasto devuelve el valor verdadero. actúan de la misma forma que SQL lo hace con los «null». gt >. Estas reglas de la lógica son una ampliación de las Leyes de Morgan sobre la negación. lt <. idiv. El operador $a << $b devuelve cierto si $a precede a $b en el orden del documento y viceversa con $a >> $b.xml")/personas/persona let $p4 := doc("personas. que son útiles cuando por alguna razón el orden de los elementos sea significativo. Ejemplo: for $p in doc("personas. Y: if ($p >> $p4) then $p else () Selecciono aquellas personas que están detrás de esta cuarta persona. cuando se enfrentan a secuencias vacías. Presenta un problema. Debe señalarse que tanto estos operadores comparativos como los aritméticos. mod. funciona correctamente y escoge la persona si todos sus gastos superan los 200. Existe una relación entre el operador all o ∀ (every) y el operador exist ∃ o (some). -.0" encoding="UTF-8"?> <persona> <nif>nif5</nif> <nombre> nombre5</nombre> <direccion> calle 5</direccion> <poblacion>pueblo3 </poblacion> <telefono> 45 </telefono> <gastos> <gasto> Pag: 28/38 . div. por eso aparece nif6 y nif1.xml")/personas/persona[4] return if ($p >> $p4) then $p else () Con: let $p4 := doc("personas. De posición: XQuery proporciona dos operadores para determinar la posición de dos nodos en el orden propio de un documento. ∀x[condición] = ~∃x[~condición] ∃x[condición] = ~x∀[~condición] Operadores En su mayoría los operadores que se utilizan en XQuery coinciden con los habituales en el resto de lenguajes de programación. ge >=. todos con su significado convencional. Comparativos: también se corresponde con los operadores habituales conocidos: eq =. ne !=. *.xml")/personas/persona[4] Selecciono la cuarta persona de la lista de personas. Resultando: <?xml version="1.</persona> El operador every reconocido en lógica con all (todos). le <=. los más utilizados son los siguientes: Aritméticos: +.

aunque ahora con secuencias de operandos. Ejemplo de execpt o diferencia. intersect. sin cambiar el orden interno que éstas tenían en el documento original. personas de pueblo1 con el atributo edad: for $p in doc("personas. Por ejemplo. Son los elementos que están en el primer grupo y no están en el segundo. parte de dos secuencias de nodos y devuelve otra con todos los nodos presentes en el primer operando que no figuran en la segunda. siempre que se mantenga el principio de que ningún nodo aparezca dos o más veces. El operador except. Ejemplo de intersect o intersección. Ejemplo de union: for $p in doc("personas. son éstos: union. y except. En el caso de que algún operando involucrado en estas operaciones contenga un ítem que no sea un nodo se declara el error correspondiente. Debe señalarse que se pueden combinar estos operadores de secuencia.xml")/personas/persona[@edad] return $p En este caso devuelve: <?xml version="1.xml")/personas/persona[2] return $p Donde selecciono la primera y la segunda persona.xml")/personas/persona[poblacion="pueblo1"] intersect doc("personas.<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> De Secuencia: estos operadores actúan combinando secuencias para obtener como resultado otra secuencia.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. Los operadores union (que también admite la forma léxica: | ) e intersect equivalen a las correspondientes operaciones conjuntistas.xml")/personas/persona[1] union doc("personas. Por ejemplo: Pag: 29/38 .

floor() y ceiling(). hay que destacar aquellas funciones que acceden a tipos de información de un nodo.xml")/personas/persona[1])) da como resultado la cadena el siguiente texto: <?xml version="1. por ejemplo: string((doc("personas. ends-with(). Más específicamente.xml")/personas/persona[poblacion="pueblo1"] except doc("personas. Además de las citadas. la función opuesta es exists().for $p in doc("personas. La primera tiene el correspondiente significado booleano basado en negación. empty() es una función que detecta si una secuencia es vacía. coun(). Como en SQL son muy usadas funciones tales como: mino. starts-with(). lower-case() que incluso pueden adaptarse para admitir como parámetros distintos tipos de datos simples. substring(). max(). cuyo significado. que devuelve el tipo del valor del nodo. Otras funciones familiares de XQuery son las que operan sobre números: round().xml")/personas/persona[@edad] return $p Son las personas de pueblo1 no tienen definida la edad. string-length(). uppercase(). avg(). En este caso devuelve: <?xml version="1. algunas de ellas ya las hemos definido y utilizado como es el caso de doc(). sum(). como string() que devuelve el valor de cadena de un nodo o la ya utilizada data(). etc. En este grupo son especialmente usadas: not(). Respecto a las funciones propias de XML que no suelen estar en otros lenguajes.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 están pensadas específicamente para procesar XML.0" encoding="UTF-8"?> nif1 nombre1 Pag: 30/38 . que indica si una secuencia contiene al menos un ítem.. el valor de string() incluye la representación del texto encontrado en el nodo y sus descendientes. y sobre cadenas: concat(). empty() y exists(). concatenándolos según el orden de aparición en el documento. parámetros y resultados son suficientemente evidentes.

pues depende de múltiples circunstancias. renombrar. o incluso de sistemas de gestión de bases de datos relacionales. Depende de la versión de Oxygen instalado. Para ello indicaremos qué hacer en cada caso. construidas sobre la biblioteca básica que proporciona el lenguaje. Esta posibilidad de recurrir a XQuery desde otros lenguajes hace que las implementaciones XQuery forme parte de entornos de programación basados en Java o C#. Pag: 31/38 . y debe tener en cuenta una gran cantidad de requisitos. de forma que este entorno proporciona a XQuery tanto funciones externas como variables.5 u otra librería del mismo tipo.net/update_ext.com/xquery-update • http://exist.html • http://stackoverflow. Saxon-EE permite modificaciones.xmlplease. Para obtener más información. pero que por el momento no forma parte de la familia XML. Para poder manejar estos elementos es preciso ajustar Oxygen para que permita realizar operaciones de modificación. un tema al cual nos referiremos brevemente en el último capítulo.com/questions/ 5335046/xquery-update-insert-or-replace-depending-ifnode-exists-not-possible. borrado.calle 1 pueblo1 23 Para finalizar.0. El desarrollo de XQuery es uno de los más laboriosos. reemplazar.Actualización (inserción. modificación) Hasta el momento solo se ha podido realizar consultas sobre los contenidos ya almacenados en la base de datos XML. cambiar y/o borrar entradas dentro de la base de datos. Lo presentado en este capítulo es sólo una introducción a estos puntos. 6. sourceforge. vea las páginas • http://www. Quizás nuestro amigo quiera insertar. En este caso Saxo-EE Xquery 9. es importante señalar que en XQuery es perfectamente posible crear funciones definidas por el usuario..3. con el objetivo de poner de manifiesto los problemas a los que se tiene que enfrentar la nueva Web para alcanzar todas sus posibilidades. El primer paso es cambiar desde Tools-External Tools-Preferences tenemos que cambiar la librería Saxon a Saxon-EE. A lo anterior hay que añadir el propio problema del desarrollo de Sistemas de Gestión de Bases de Datos que manejen documentos XML. En particular estas funciones definidas por el usuario permiten abreviar consultas muy largas.

Una vez cambiada la libería Saxon tengo que comprobar que existe una extensión de archivos xu asociados asociado al “Editor Xquery”. El escenario de ejecución Xquery se configura desde el siguiente Icono: Desde este punto accedemos a la configuración de los escenarios: Pag: 32/38 . como se puede comprobar en la siguiente ventana: Además de esto es preciso configurar y ajustar el escenario de ejecución para Saxon EE. se comprueba desde la misma ventana anterior buscando “File Types”.

podemos cambiar la primera etiqueta <nif> de una persona por la etiqueta <cif> con la siguiente sentencia: rename node doc("personas. Por ejemplo. Se le puede cambiar el nombre a un nodo con la sentencia rename.xml")/personas/persona/nif return rename node $nif as "cif" Para volver a cambiar todos los cif por nif: Pag: 33/38 .Donde ajusto el escenario por defecto a la librería Saxon-EE: Una vez hechos estos procesos podemos comenzar a modificar nuestros documentos XML desde una consulta Xquery. RENOMBRADO DE NODOS. Rename funciona nodo a nodo.xml")/personas/persona[1]/nif as "cif" El contenido de la etiqueta <nif> se pasa integro a la etiqueta <cif> y se tendría que comprobar la descripción del documento y los tipos de datos en el proceso de cambio de dicha etiqueta. Es posible renombrar un elemento o grupo de elementos determinados. Si se quiere cambiar todos los nif de personas por cif se utilizaría el siguiente código: for $nif in doc("personas.

Una sentencia equivalente para insertar al principio del fichero.xml".for $cif in doc("personas. Ambas utilizan como referencia al primer nodo ("[1]"). sería sustituyendo la última línea 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. solo cambiaría "before" por "after".xml")/personas Pag: 34/38 . Si se quiere insertar después.xml")/personas/persona/cif return rename node $cif as "nif" INSERCIÓN Se quiera añadir un nuevo baile en la base de datos.xml")/personas/persona[1] Este código inserta el nodo indicado en fichero “personas. Los datos son: La inserción se realizaría 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. sin tener que referenciar a nodo alguno de la base de datos. El nodo se insertará antes del primer nodo de la base de datos (por la clausula "before").

Por ejemplo. <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. se realizaría de la siguiente manera: as last into doc("personas. pasa exactamente lo mismo que con la sentencia insert en una base de datos. Pues resulta.Cada vez que se pulsa una ejecución introduce un nuevo elemento repetido.xml")/personas/persona[1] MODIFICACIÓN.xml")/personas/persona[1] O seleccionar una variable y añadirlos al lote o uno a uno en un bucle for. que antes se insertaron de forma automática varios nodos idénticos.xml")/personas Se puede incluso añadir una lista de nodos entre paréntesis 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>. lo que se desea es insertar al final de la base de datos.xml")/personas/persona[poblacion ="pueblo1"] return insert node $clnPbl1 before doc("personas. Se va a proceder a cambiar el nif del primero cambiando nifnuevo por nif-n1 La modificación se realizaría de la siguiente manera: replace value of node Pag: 35/38 . repetir los de “pueblo1” usando una variable: let $clnPbl1 := doc("personas. sin referenciar a ningún nodo. Si por el contrario.

Ir a la pestaña "XML_Libraries". HTML. por lo que es posible ejecutar el siguiente código para borrar todos los clientes de Archidona: let $archidona := doc("personas. Para hacer una copia de seguridad se selecciona XML y se prodecerá a volcar la información. Pag: 36/38 . Seleccionar "DB_BailesDeSalon. 7. Ver Figura 6. Por ejemplo. es un buen momento para exportar el contenido a un fichero XML externo. XHTML. es más cómodo declarar la variable en un bucle for y borrar nodo a nodo. replace value of node doc("personas..xml")/personas/persona[1]/nif with "nif-n1" Se pueden realizar varias modificaciones a la vez. la codificación y el formato t. Cambiamos el nif del primero a “nif-n1c” y el del segundo a “nif-n2c”: replace value of node doc("personas. Por ejemplo. podemos borrarlos. o texto).xml")/personas/persona[poblacion = "Archidona"] return delete node $archidona Aunque.xml".23. Qizx Studio nos permite realizarlo de manera muy sencilla: 1. separándolas por comas.xml")/personas/persona[1]. delete node doc("personas.xml")/personas/persona[1]/nif with "nif-n1c". se van a borrar la primera y la segunda persona: delete node doc("personas.Exportación de librerías XML Después de realizar todos los cambios en la base de datos.doc("personas. botón derecho y pulsar "Export to File . fijar todas las poblaciones a Antequera: for $poblacion in doc("personas. Aparece una nueva ventana en la que se puede seleccionar el fichero de salida. 2..xml")/personas/persona/poblacion return replace value of node $poblacion with "Antequera" BORRADO Después añadir y modificar elementos. para modificar varios nodos es necesario usar un bucle for.".xml")/personas/persona[2]/nif with "nif-n2c" Replace no permite modificar un lista de nodos entre paréntesis.xml")/personas/persona[2] Cuidado con los borrados múltiples que pueden dejar el fichero vacío.. De esta manera se podría tener una copia de seguridad en caso de contingencia. (XML.. Delete permite borrar listas de nodos.

Como desventaja es que una vez pasada la lectura. Por último tenemos otra API llamada SAX (Simple API for XML). que permite representar documentos HTML y/o XML de manera que las aplicaciones que la utilicen puedan representar el documento en forma de árbol. cambiando la estructura del árbol. De esta manera tendremos en fichero los resultados de la consulta. resolver URIs.. Otra manera de acceder a los nodos de los documentos XML es mediante la librería DOM (Document Object Model). etc. se habló anteriormente de cómo utilizar expresiones FLWOR para que devuelvan código HTML. Es una librería que inicialmente se utilizaba en Java pero que en la actualidad es posible utilizarla en muchos lenguajes de programación.. no se puede volver a atrás (en contraposición de DOM que sí se permite). modificando los propios nodos o la información que contienen.Figura Exportación de librerías XML en Qizx Para finalizar. En resumen. se puede recorrer buscando información. párig_establecer secuencias. para acceder a nodos. funciones para tratamiento de valores numéricos. Esta API es un estándar de acceso aprobada por la W3C. Una vez que se está en la pestaña "XQuery" y se ejecuta la consulta. Hay que pusar el botón de exportación de resultados "Save results" y aparecerá una ventana similar a la de la Figura anterior. El inconveniente es que es necesario conocer un lenguaje de programación para hacer uso de esta API. en la parte derecha muestra los resultados.Otras funciones o librerías.. Pero XQuery no es solamente lo que se ha visto aquí. la decisión final de utilizar una u otra solución dependerá de las necesidades que Pag: 37/38 . de manera secuencial y sin que se cargue todo el en memoria (sin generar ningún árbol). En el caso de necesitar más potencia a la hora de generar las consultas. para tratar strings. En la actualidad la práctica mayoría de los navegadores la tienen implementada. En este libro se ha elegido XQuery pues permite utilizarse en los grandes sistemas SGBD y también en pequeñas aplicaciones con motores de BD XML nativas como Qizx. Una vez cargado el árbol. La principal ventaja de usar un parser SAX es que el documento XML se lee una única vez. Existen funciones para acceder a nodos padre. DOM es una interfaz de programación de aplicaciones (API). funciones para tratar fechas/horas. se recomienda consultar las funciones de Xpath20. existen muchas maneras de manipular documentos XML. 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 línea en C/C++ o Java. 8. El procedimiento para exportar los resultados es muy sencillo. En cualquier caso. Esto redunda en que los analizadores SAX son más eficientes en la memoria utilizada que los DOM. Recordemos que XQuery usa por XPath y éste tiene muchas funcionalidades que no se han tratado en este capítulo. No será necesario tener conocimientos de programación en lenguajes como C/C++ o Java para manejar API's como SAX o DOM.

haciendo especial hincapié en el almacenamiento y el tratamiento de la información.tenga el proyecto al que vaya a implantarse. Pag: 38/38 .