XQuery - Guía rápida

Que es XQuery

XQuery es un lenguaje funcional que se utiliza para recuperar información almacenada en formato XML. XQuery se puede utilizar en documentos XML, bases de datos relacionales que contienen datos en formatos XML o bases de datos XML. XQuery 3.0 es una recomendación del W3C del 8 de abril de 2014.

La definición de XQuery dada por su documentación oficial es la siguiente:

XQuery es un lenguaje estandarizado para combinar documentos, bases de datos, páginas web y casi cualquier otra cosa. Está muy extendido. Es poderoso y fácil de aprender. XQuery está reemplazando los lenguajes de middleware propietarios y los lenguajes de desarrollo de aplicaciones web. XQuery está reemplazando programas complejos de Java o C ++ con unas pocas líneas de código. XQuery es más simple de trabajar y más fácil de mantener que muchas otras alternativas.

Caracteristicas

  • Functional Language - XQuery es un lenguaje para recuperar / consultar datos basados ​​en XML.

  • Analogous to SQL - XQuery es para XML lo que SQL es para bases de datos.

  • XPath based - XQuery usa expresiones XPath para navegar a través de documentos XML.

  • Universally accepted - XQuery es compatible con las principales bases de datos.

  • W3C Standard - XQuery es un estándar W3C.

Beneficios de XQuery

  • Con XQuery, se pueden recuperar datos tanto jerárquicos como tabulares.

  • XQuery se puede utilizar para consultar estructuras gráficas y de árbol.

  • XQuery se puede utilizar directamente para consultar páginas web.

  • XQuery se puede utilizar directamente para crear páginas web.

  • XQuery se puede utilizar para transformar documentos xml.

  • XQuery es ideal para bases de datos basadas en XML y bases de datos basadas en objetos. Las bases de datos de objetos son mucho más flexibles y potentes que las bases de datos puramente tabulares.

Este capítulo explica cómo configurar la biblioteca XQuery en un entorno de desarrollo local.

Estamos utilizando un procesador XQuery independiente de código abierto, Saxon Home Edition (Saxon-HE), que se utiliza ampliamente. Este procesador es compatible con XSLT 2.0, XQuery 3.0 y XPath 3.0 y está altamente optimizado para el rendimiento. El procesador Saxon XQuery se puede utilizar sin tener ninguna base de datos XML. Usaremos un documento XML simple como nuestra base de datos en nuestros ejemplos.

Para utilizar el procesador Saxon XQuery, debe tener saxon9he.jar, saxon9-test.jar, saxon9-unpack, saxon9-xqj.jar en el classpath de su aplicación. Estos archivos jar están disponibles en el archivo de descargaSaxonHE9-6-0-1J.zipDescargue SaxonHE9-6-0-1J.zip .

Ejemplo

Usaremos el procesador Saxon XQuery basado en Java para probar books.xqy, un archivo que contiene la expresión XQuery con nuestro documento XML de muestra, es decir, books.xml.

En este ejemplo, veremos cómo escribir y procesar una consulta para obtener los elementos del título de los libros cuyo precio es superior a 30.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

books.xqy

for $x in doc("books.xml")/books/book
where $x/price>30
return $x/title

XQueryTester.java

package com.tutorialspoint.xquery;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;

import com.saxonica.xqj.SaxonXQDataSource;

public class XQueryTester {
   public static void main(String[] args){
      try {
         execute();
      }
      
      catch (FileNotFoundException e) {
         e.printStackTrace();
      }
      
      catch (XQException e) {
         e.printStackTrace();
      }
   }

   private static void execute() throws FileNotFoundException, XQException{
      InputStream inputStream = new FileInputStream(new File("books.xqy"));
      XQDataSource ds = new SaxonXQDataSource();
      XQConnection conn = ds.getConnection();
      XQPreparedExpression exp = conn.prepareExpression(inputStream);
      XQResultSequence result = exp.executeQuery();
      
      while (result.next()) {
         System.out.println(result.getItemAsString(null));
      }
   }	
}

Pasos para ejecutar XQuery contra XML

  • Step 1 - Copie XQueryTester.java en cualquier ubicación, por ejemplo, E: > java

  • Step 2 - Copie books.xml en la misma ubicación, E: > java

  • Step 3 - Copie books.xqy en la misma ubicación, E: > java

  • Step 4- Compile XQueryTester.java usando la consola. Asegúrese de tener JDK 1.5 o posterior instalado en su máquina y que las rutas de clases estén configuradas. Para obtener detalles sobre cómo usar JAVA, consulte nuestro Tutorial de JAVA

E:\java\javac XQueryTester.java
  • Step 5 - Ejecutar XQueryTester

E:\java\java XQueryTester

Salida

Obtendrá el siguiente resultado:

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

Ejemplo de comprensión

  • books.xml representa los datos de muestra.

  • books.xqy representa la expresión XQuery que se ejecutará en books.xml. Entenderemos la expresión en detalle en el próximo capítulo.

  • XQueryTester, un programa ejecutor de XQuery basado en Java, lee books.xqy, lo pasa al procesador de expresiones XQuery y ejecuta la expresión. Luego se imprime el resultado.

Ejemplo

A continuación se muestra un documento XML de muestra que contiene los registros de una librería de varios libros.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

A continuación se muestra un documento de Xquery de muestra que contiene la expresión de consulta que se ejecutará en el documento XML anterior. El propósito es obtener los elementos del título de aquellos nodos XML donde el precio es superior a 30.

books.xqy

for $x in doc("books.xml")/books/book
where $x/price>30
return $x/title

Resultado

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

Verificar resultado

Para verificar el resultado, reemplace el contenido de books.xqy (dado en el capítulo Configuración del entorno ) con la expresión XQuery anterior y ejecute el programa java XQueryTester.

Expresiones XQuery

Entendamos cada parte de la expresión XQuery anterior.

Uso de funciones

doc("books.xml")

doc () es una de las funciones de XQuery que se utiliza para localizar la fuente XML. Aquí hemos pasado "books.xml". Teniendo en cuenta la ruta relativa, books.xml debería estar en la misma ruta donde está presente books.xqy.

Uso de expresiones XPath

doc("books.xml")/books/book

XQuery utiliza en gran medida expresiones XPath para localizar la parte necesaria de XML en la que se va a realizar la búsqueda. Aquí hemos elegido todos los nodos de libros disponibles en el nodo de libros.

Iterar los objetos

for $x in doc("books.xml")/books/book

XQuery trata los datos xml como objetos. En el ejemplo anterior, $ x representa el nodo seleccionado, mientras que el bucle for itera sobre la colección de nodos.

Aplicar la condición

where $x/price>30

Como $ x representa el nodo seleccionado, "/" se usa para obtener el valor del elemento requerido; La cláusula "where" se utiliza para poner una condición en los resultados de búsqueda.

Devuelve el resultado

return $x/title

Como $ x representa el nodo seleccionado, "/" se usa para obtener el valor del elemento requerido, precio, título; La cláusula "return" se utiliza para devolver los elementos de los resultados de búsqueda.

FLWOR es un acrónimo que significa "For, Let, Where, Order by, Return". La siguiente lista muestra lo que representan en una expresión FLWOR:

  • F - Para: selecciona una colección de todos los nodos.

  • L - Let: coloca el resultado en una variable XQuery.

  • W - Donde: selecciona los nodos especificados por la condición.

  • O - Ordenar por: ordena los nodos especificados según los criterios.

  • R - Devolver: devuelve el resultado final.

Ejemplo

A continuación se muestra un documento XML de muestra que contiene información sobre una colección de libros. Usaremos una expresión FLWOR para recuperar los títulos de aquellos libros con un precio superior a 30.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

El siguiente documento de Xquery contiene la expresión de consulta que se ejecutará en el documento XML anterior.

books.xqy

let $books := (doc("books.xml")/books/book)
return <results>
{
   for $x in $books
   where $x/price>30
   order by $x/price
   return $x/title
}
</results>

Resultado

<title lang="en">Learn XQuery in 24 hours</title>
<title lang="en">Learn .Net in 24 hours</title>

Verificar resultado

Para verificar el resultado, reemplace el contenido de books.xqy (dado en el capítulo Configuración del entorno ) con la expresión XQuery anterior y ejecute el programa java XQueryTester.

XQuery también se puede utilizar fácilmente para transformar un documento XML en una página HTML. Eche un vistazo al siguiente ejemplo para comprender cómo lo hace XQuery.

Ejemplo

Usaremos el mismo archivo books.xml. El siguiente ejemplo utiliza XQuery para extraer datos de books.xml y crear una tabla HTML que contiene los títulos de todos los libros junto con sus respectivos precios.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>70.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

A continuación se muestra la expresión Xquery que se ejecutará en el documento XML anterior.

books.xqy

let $books := (doc("books.xml")/books/book)
return <table><tr><th>Title</th><th>Price</th></tr>
{
   for $x in $books   
   order by $x/price
   return <tr><td>{data($x/title)}</td><td>{data($x/price)}</td></tr>
}
</table>
</results>

Resultado

<table>
   <tr>
      <th>Title</th>
      <th>Price</th>
   </tr>
   <tr>
      <td>Learn XPath in 24 hours</td>
      <td>16.50</td>
   </tr>   
   <tr>
      <td>Learn Java in 24 Hours</td>
      <td>30.00</td>
   </tr>
   <tr>
      <td>Learn XQuery in 24 hours</td>
      <td>50.00</td>
   </tr>   
   <tr>
      <td>Learn .Net in 24 hours</td>
      <td>70.50</td>
   </tr>
</table>

Verificar resultado

Para verificar el resultado, reemplace el contenido de books.xqy (dado en el capítulo Configuración del entorno ) con la expresión XQuery anterior y ejecute el programa java XQueryTester.

Expresiones XQuery

Aquí hemos utilizado las siguientes expresiones XQuery:

  • función data () para evaluar el valor del elemento de título, y

  • {} operador para decirle al procesador XQuery que considere data () como una función. Si no se usa el operador {}, entonces los datos () se tratarán como texto normal.

XQuery es compatible con XPath. Utiliza expresiones XPath para restringir los resultados de búsqueda en colecciones XML. Para obtener más detalles sobre cómo utilizar XPath, consulte nuestro Tutorial de XPath .

Recuerde la siguiente expresión XPath que hemos utilizado anteriormente para obtener la lista de libros.

doc("books.xml")/books/book

Ejemplos de XPath

Usaremos el archivo books.xml y le aplicaremos XQuery.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
   
</books>

Hemos proporcionado aquí tres versiones de una declaración XQuery que cumplen el mismo objetivo de mostrar los títulos de los libros con un valor de precio superior a 30.

XQuery - Versión 1

(: read the entire xml document :)
let $books := doc("books.xml")

for $x in $books/books/book
where $x/price > 30
return $x/title

Salida

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

XQuery - Versión 2

(: read all books :)
let $books := doc("books.xml")/books/book

for $x in $books
where $x/price > 30
return $x/title

Salida

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

XQuery - Versión 3

(: read books with price > 30 :)
let $books := doc("books.xml")/books/book[price > 30]

for $x in $books
return $x/title

Salida

<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>

Verificar el resultado

Para verificar el resultado, reemplace el contenido de books.xqy (dado en el capítulo Configuración del entorno ) con la expresión XQuery anterior y ejecute el programa java XQueryTester.

Las secuencias representan una colección ordenada de elementos donde los elementos pueden ser de tipos similares o diferentes.

Crear una secuencia

Las secuencias se crean utilizando paréntesis con cadenas entre comillas o comillas dobles y números como tales. Los elementos XML también se pueden utilizar como elementos de una secuencia.

Expresión XQuery

let $items := ('orange', <apple/>, <fruit type="juicy"/>, <vehicle type="car">sentro</vehicle>, 1,2,3,'a','b',"abc")
let $count := count($items)
return
<result>
   <count>{$count}</count>
   
   <items>
      {
	     for $item in $items
         return <item>{$item}</item>
      }
   </items>
   
</result>

Salida

<result>
   <count>10</count>
   <items>
      <item>orange</item>
      <item>
         <apple/>
      </item>
      <item>
         <fruit type="juicy"/>
      </item>
      <item>
         <vehicle type="car">Sentro</vehicle>
      </item>
      <item>1</item>
      <item>2</item>
      <item>3</item>
      <item>a</item>
      <item>b</item>
      <item>abc</item>
   </items>
</result>

Ver los elementos de una secuencia

Los elementos de una secuencia se pueden iterar uno por uno, usando índice o por valor. El ejemplo anterior iteraba los elementos de una secuencia uno por uno. Veamos las otras dos formas en acción.

Expresión XQuery (índice)

let $items := (1,2,3,4,5,6)
let $count := count($items)
return
   <result>
      <count>{$count}</count>
      
      <items>
      {
         for $item in $items[2]
         return <item>{$item}</item>
      }
      </items>
      
   </result>

Salida

<result>
   <count>6</count>
   <items>
      <item>2</item>
   </items>
</result>

Expresión de XQuery (valor)

let $items := (1,2,3,4,5,6)
let $count := count($items)
return
   <result>
      <count>{$count}</count>
      
      <items>
      {
         for $item in $items[. = (1,2,3)]
         return <item>{$item}</item>
      }
      </items>
      
   </result>

Salida

<result>
   <count>6</count>
   <items>
      <item>1</item>
      <item>2</item>
      <item>3</item>
   </items>
</result>

La siguiente tabla enumera las funciones de secuencia de uso común proporcionadas por XQuery.

No Señor Nombre y descripción
1

contar ($ seq como elemento () *)

Cuenta los elementos en una secuencia.

2

suma ($ seq como elemento () *)

Devuelve la suma de los elementos en una secuencia.

3

avg ($ seq como elemento () *)

Devuelve el promedio de los elementos en una secuencia.

4

min ($ seq como elemento () *)

Devuelve el elemento de valor mínimo en una secuencia.

5

max ($ seq como elemento () *)

Devuelve el elemento de valor máximo en una secuencia.

6

valores-distintos ($ seq como elemento () *)

Las devoluciones seleccionan elementos distintos de una secuencia.

7

subsecuencia ($ seq como elemento () *, $ startLoc como xs: doble, $ longitud como xs: doble)

Devuelve un subconjunto de la secuencia proporcionada.

8

insert-before ($ seq as item () *, $ position as xs: integer, $ inserts as item () *)

Inserta un elemento en una secuencia.

9

eliminar ($ seq como elemento () *, $ posición como xs: integer)

Elimina un elemento de una secuencia.

10

reverse ($ seq as item () *)

Devuelve la secuencia inversa.

11

índice de ($ seq como anyAtomicType () *, $ objetivo como anyAtomicType ())

Devuelve índices como números enteros para indicar la disponibilidad de un elemento dentro de una secuencia.

12

último()

Devuelve el último elemento de una secuencia cuando se usa en una expresión de predicado.

13

posición()

Se utiliza en expresiones FLOWR para obtener la posición de un elemento en una secuencia.

La siguiente tabla enumera las funciones de manipulación de cadenas de uso común proporcionadas por XQuery.

No Señor Nombre y descripción
1

longitud de cadena ($ cadena como xs: cadena) como xs: entero

Devuelve la longitud de la cadena.

2

concat ($ entrada como xs: anyAtomicType?) como xs: string

Devuelve la cadena concatenada como salida.

3

string-join ($ secuencia como xs: cadena *, $ delimitador como xs: cadena) como xs: cadena

Devuelve la combinación de elementos en una secuencia separados por un delimitador.

La siguiente tabla enumera las funciones de fecha de uso común proporcionadas por XQuery.

No Señor Nombre y descripción
1

fecha actual()

Devuelve la fecha actual.

2

tiempo actual()

Devuelve la hora actual.

3

fecha y hora actual ()

Devuelve tanto la fecha actual como la hora actual.

A continuación se muestra la lista de funciones de expresión regular de uso común proporcionadas por XQuery

No Señor Nombre y descripción
1

coincidencias ($ input, $ regex)

Devuelve verdadero si la entrada coincide con la expresión regular proporcionada.

2

reemplazar ($ input, $ regex, $ string)

Reemplaza la cadena de entrada coincidente con la cadena dada.

3

tokenizar ($ entrada, $ regex)

Devuelve una secuencia de elementos que coinciden con la expresión regular.

XQuery proporciona una construcción if-then-else muy útil para verificar la validez de los valores de entrada pasados. A continuación se muestra la sintaxis de la construcción if-then-else.

Sintaxis

if (condition) then
 ... 
else
 ...

Ejemplo

Usaremos el siguiente archivo books.xml y le aplicaremos la expresión XQuery que contiene una construcción if-then-else para recuperar los títulos de esos libros con un valor de precio mayor que 30.

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author>
      <year>2013</year>
      <price>50.00</price>
   </book>
   
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
</books>

La siguiente expresión XQuery se aplicará en el documento XML anterior.

books.xqy

<result>
{
   if(not(doc("books.xml"))) then (
      <error>
         <message>books.xml does not exist</message>
      </error>
   )
   else ( 
      for $x in doc("books.xml")/books/book	
      where $x/price>30
      return $x/title
   )
}
</result>

Salida

<result>
   <title lang="en">Learn .Net in 24 hours</title>
   <title lang="en">Learn XQuery in 24 hours</title>
</result>

Verificar el resultado

Para verificar el resultado, reemplace el contenido de books.xqy (dado en el capítulo Configuración del entorno ) con la expresión XQuery anterior y ejecute el programa java XQueryTester.

XQuery proporciona la capacidad de escribir funciones personalizadas. A continuación se enumeran las pautas para crear una función personalizada.

  • Usa la palabra clave declare function para definir una función.

  • Utilice los tipos de datos definidos en el esquema XML actual

  • Encierra el cuerpo de función dentro de llaves.

  • Prefije el nombre de la función con un espacio de nombres XML.

La siguiente sintaxis se utiliza al crear una función personalizada.

Sintaxis

declare function prefix:function_name($parameter as datatype?...)
as returnDatatype?
{
   function body...
};

Ejemplo

El siguiente ejemplo muestra cómo crear una función definida por el usuario en XQuery.

Expresión XQuery

declare function local:discount($price as xs:decimal?,$percentDiscount as xs:decimal?)
as xs:decimal? {
   let $discount := $price - ($price * $percentDiscount div 100) 
   return $discount
};

let $originalPrice := 100

let $discountAvailed := 10

return ( local:discount($originalPrice, $discountAvailed))

Salida

90

Verificar el resultado

Para verificar el resultado, reemplace el contenido de books.xqy (dado en el capítulo Configuración del entorno ) con la expresión XQuery anterior y ejecute el programa java XQueryTester.