Solución de XQuery con escenario de libros
Solución a cuestións do enunciado 1
1. Listar el título de todos los libros.
doc("libros.xml")//libro/titulo
También:
for $libros in doc("libros.xml")/bib/libro/titulo
return $libros
2. Listar año y título de todos los libros, ordenados por el año.
for $a in doc("libros.xml")//libro
order by $a/@ano
return
<libro>
{$a/@ano}
{$a/titulo}
</libro>
3. Listar los libros cuyo precio sea 65.95
for $a in doc("libros.xml")//libro
where $a/prezo = "65.95"
return $a
4. Listar los libros publicados antes del año 2000
for $a in doc("libros.xml")//libro
where $a/@ano < "2000"
return $a
5. Listar año y título de los libros publicados por Addison-Wesley después del año 1992.
for $a in doc("libros.xml")/bib/libro
where $a/editorial = "Addison-Wesley" and $a/@ano > 1991
return
<libro ano="{ $a/@ano }">
{ $a/titulo }
</libro>
6. Listar año y título de los libros que tienen más de un autor.
for $a in doc("../prueba/libros.xml")/bib/libro
return
if (count($a/autor) > 1)
then <libro ano="{ $a/@ano }">
{ $a/titulo }
else ()
</libro>
7. Listar año y título de los libros que tienen no tienen autor.
for $a in doc("../prueba/libros.xml")/bib/libro
return
if (count($a/autor) = 0)
then <libro ano="{ $a/@ano }">
{ $a/titulo }
</libro>
Otra opción:
for $a in doc("../prueba/libros.xml")//libro
where empty($a/autor)
return <libro ano="{ $a/@ano }">
{ $a/titulo }
</libro>
8. Mostrar los apellidos de los autores que aparecen en el documento, sin repeticiones, ordenadosalfabéticamente.
for $a in distinct-values(doc("../prueba/libros.xml")
//autor/apelido)
order by $a
return <apelidos>{ $a }</apelidos>
9. Por cada libro, listar agrupado en un elemento <result> su titulo y autores
for $b in doc("../prueba/libros.xml")//libro
return
<result>
{ $b/titulo }
<autores>
{
for $a at $i in $b/autor
return <autor>{string($a)}</autor>
}
</autores>
</result>
10. Por cada libro, obtener su título y el número de autores, agrupados en un elemento <libro>
for $b in doc("../prueba/libros.xml")//libro
return
<libro>
{ $b/titulo }
<numeroAutores>
{count($b/autor)}
</numeroAutores>
</libro>
11. Generar un documento html con un encabezado que diga “Listado de libros” seguido de una tabla de 3 columnas, en la que se muestre el titulo, editorial y precio de cada libro. La tabla deberá tener bordes y la primera fila tendrá un formato especial con los nombres de las columnas. Las columnas de título y editorial irán alineadas a la izquierda, y el precio a la derecha.
<html>
<head>
<title> Listado de libros </title>
</head>
<body>
<table border="1">
<caption>Listado de libros</caption>
<th> Titulo </th>
<th> Editorial </th>
<th> Precio </th>
{
for $a in doc("../prueba/libros.xml")/bib/libro
return
<tr>
<td align ="left"> <i> { string( $a/titulo ) } </i> </td>
<td align ="left"> { string( $a/editorial ) } </td>
<td align ="right"> { string( $a/prezo) } </td>
</tr>
}
(: No lo pide el enunciado, pero así se podría mostrar el precio medio de los libros :)
{
let $a := doc("../prueba/libros.xml")/bib/libro
return
<tr>
<td> {avg( $a/prezo ) } </td>
</tr>
}
</table>
</body>
</html>
12. Generar el siguiente documento html con la información de los libros del autor Stevens. El valor precio total es un campo calculado utilizando una consulta con una cláusula let.
<html>
<head>
<title> Libros de Stevens </title>
</head>
<body>
<table border="1">
<caption>Listado de libros</caption>
<th> Titulo </th>
<th> Precio </th>
{
for $a in doc("../prueba/libros.xml")//libro
where $a/autor/apelido="Stevens"
return
<tr>
<td>{$a/titulo}</td>
<td>{$a/prezo}</td>
</tr>
}
{
let $a := doc("../prueba/libros.xml")/bib/libro
where $a/autor/apelido="Stevens"
return
<tr>
<td> {sum( $a/prezo ) } </td>
</tr>
}
</table>
</body>
</html>
Solución a cuestións do enunciado 2
1. los títulos de los libros con la etiqueta "titulo".
for $titulo in /bookstore/book/title/text()
return <titulo>{$titulo}</titulo>
2. los libros cuyo precio sea menor o igual a 30. Primero incluyendo la condición en la cláusula "where" y luego en la ruta del XPath.
3. sólo el título de los libros cuyo precio sea menor o igual a 30.
for $libro in /bookstore/book
where $libro/price <= 30
return $libro
También:
for $libro in /bookstore/book[price<=30]
return $libro
4. sólo el título sin atributos de los libros cuyo precio sea menor o igual a 30.
for $libro in /bookstore/book
where $libro/price <= 30
return $libro/title
También:
for $libro in /bookstore/book[price<=30]
return $libro/title
5. el título y el autor de los libros del año 2005, y etiquetar cada uno de ellos con "lib2005".
for $libro in /bookstore/book
where $libro/year=2005
return <lib2005>{$libro/title,$libro/author}</lib2005>
for $libro in /bookstore/book
where $libro/year=2005
return <lib2005>{$libro/title}{$libro/author}</lib2005>
6. los años de publicación, primero con "for" y luego con "let" para comprobar la diferencia entre ellos. Etiquetar la salida con "publicacion".
Con for:
for $year in /bookstore/book/year
return <publicacion>{$year}</publicacion>
Con let:
let $year := /bookstore/book/year
return <publicacion>{$year}</publicacion>
7. los libros ordenados primero por "category" y luego por "title" en una sola consulta.
for $libro in /bookstore/book
order by $libro/@category,$libro/title
return $libro
8. cuántos libros hay, y etiquetarlo con "total".
let $num_libro := count(/bookstore/book)
return <total>{$num_libro}</total>
9. los títulos de los libros y al final una etiqueta con el número total de libros.
let $total := count (/bookstore/book),
$titulos := (
for $libro in /bookstore/book/title
return <titulo>{$libro/text()}</titulo>)
return
<resultado>
{$titulos}
<total_libros>{$total}</total_libros>
</resultado>
10. el precio mínimo y máximo de los libros.
let $max := max(/bookstore/book/price),
$min := min(/bookstore/book/price)
return
<resultado>
<max>{$max}</max>
<min>{$min}</min>
</resultado>
11. el título del libro, su precio y su precio con el IVA incluido, cada uno con su propia etiqueta. Ordénalos por precio con IVA.
for $libro in /bookstore/book
let $precio_iva := ($libro/price * 1.21)
order by $precio_iva
return
<libro>
<titulo>{$libro/title/text()}</titulo>
<precio>{$libro/price/text()} €</precio>
<precio_iva>{$precio_iva} €</precio_iva>
</libro>
También:
for $libro in /bookstore/book
order by $libro/price * 1.21
return
<libro>
<titulo>{$libro/title/text()}</titulo>
<precio>{$libro/price/text()} €</precio>
<precio_iva>{$libro/price * 1.21} €</precio_iva>
</libro>
12. la suma total de los precios de los libros con la etiqueta "total".
let $libros := /bookstore/book
return <total>{sum($libros/price)}</total>
13. cada uno de los precios de los libros, y al final una nueva etiqueta con la suma de los precios.
let $libros := /bookstore/book
return <total>{sum($libros/price)}</total>
14. el título y el número de autores que tiene cada título en etiquetas diferentes.
for $libro in /bookstore/book
return
<libro>
{$libro/title}
<autores>{count($libro/author)}</autores>
</libro>
15. en la misma etiqueta el título y entre paréntesis el número de autores que tiene ese título.
for $libro in /bookstore/book
return <libro>{$libro/title/text()} ({count($libro/author)})</libro>
16. los libros escritos en años que terminen en "3".
for $libro in /bookstore/book
where ends-with($libro/year, "3")
return $libro
17. los libros cuya categoría empiece por "C".
for $libro in /bookstore/book
where starts-with($libro/@category, "C")
return $libro
También:
for $libro in /bookstore/book[starts-with(@category, "C")]
return $libro
18. los libros que tengan una "X" mayúscula o minúscula en el título ordenados de manera descendente.
for $libro in /bookstore/book
where contains($libro/title, "x") or contains($libro/title, "X")
order by $libro/title descending
return $libro
También:
<syntaxhighlight lang="xquery" style="border: 3px dashed blue;>
for $libro in /bookstore/book
where contains(lower-case($libro/title), "x")
order by $libro/title descending
return $libro
O:
for $libro in /bookstore/book[contains(lower-case(title), "x")]
order by $libro/title descending
return $libro
19. el título y el número de caracteres que tiene cada título, cada uno con su propia etiqueta.
for $año in distinct-values(/bookstore/book/year)
return <año>{$año}</año>
20. todos los años en los que se ha publicado un libro eliminando los repetidos. Etiquétalos con "año".
for $año in distinct-values(/bookstore/book/year) return <año>{$año}</año>
21. todos los autores eliminando los que se repiten y ordenados por el número de caracteres que tiene cada autor.
for $autor in distinct-values(/bookstore/book/author)
order by string-length($autor)
return <autor>{$autor}</autor>
22. los títulos en una tabla de HTML.
<table>
{
for $libro in /bookstore/book
return
<tr>
<td>{$libro/title/text()}</td>
</tr>
}
</table>