BaseX¶
Nota
Los ejercicios que se proponen en esta relación no dejan de ser ejercicios sobre XQuery más o menos sencillos, pensados para manipular las bases de datos cargadas en el gestor.
Tomando como referencia los documentos XML diseñados en los ejercicios sobre lenguajes de marcas, resuelva lo siguiente:
En el ejercicio sobre facturas:
Cámbiele el nombre a «Mariquilla de la O» por «María de la O».
replace value of node //cliente[nombre="Mariquilla de la O"]/nombre with "María de la O"
Añada al final de todos los clientes un elemento que sea
<solvente />
.for $cliente in //cliente return insert node <solvente/> into $cliente
Elimine todos los elementos que acaba de añadir,
delete node //cliente/solvente
Cambie al cliente «c01» su identificar por «C01». Recuerde que debería también hacer el cambio de identificador en las facturas a su nombre.
for $attr in //@*[. = "c01"] return replace node $attr with attribute {fn:name($attr)} {"C01"}
Elimine los descuentos de todas las facturas.
delete node //factura/@descuento
Añada a la factura «f01» un descuento del 15%.
insert node attribute descuento {15} into //factura[@codigo="f01"]
Aumente en +5% el descuento a todas las facturas.
for $descuento in //factura/@descuento return replace node $descuento with attribute {name($descuento)} {$descuento + 5}
Elimine de todas las facturas las líneas de facturas por debajo de la segunda, es decir, todas las facturas deben quedar como mucho con dos líneas de factura (ítems).
delete node //factura/item[position() > 2]
Añada un atributo a cada factura llamado «items» que contenga la cantidad de líneas de factura que tiene.
for $factura in //factura return insert node attribute items {count($factura/item)} into $factura
Añada tres atributos a inventario llamados superreducido, reducido y normal cuyo valor sea la cantidad de productos que tienen ese tipo de IVA.
for $iva in ("normal", "reducido", "superreducido") return insert node attribute {$iva} {count(//inventario/producto[@iva=$iva])} into //inventario
En el ejercicio 8 sobre concesionarios y clientes:
Cambiar la marca del concesionario por «Dacia».
replace node /concesionario/@marca with attribute marca {"Dacia"}
Limite la velocidad máxima a 180.
for $vel in //velmax where $vel > 180 return replace value of node $vel with text {180}
Añadir un atributo con 10 Km a los coches de «km0».
for $coche in //coche where $coche/@tipo = "km0" return insert node attribute km {10} into $coche
Sustituir todos los identificadores de cliente, por su equivalente en mayúsculas (p.e. «c01» pasa a ser «C01»). Por ahora, olvide que esos identificadores también se usan como referencia en el atributo reservado y que, en consecuencia, también deberían cambiar.
for $cliente in //cliente let $id := $cliente/@id return replace node $id with attribute cliente {fn:upper-case($id)},
Repite el ejercicio anterior, pero sin olvidar los atributos reservado.
for $cliente in //cliente let $id := $cliente/@id return ( replace node $id with attribute cliente {fn:upper-case($id)}, for $reservado in //coche/@reservado[. = $id] return replace node $reservado with attribute reservado {fn:upper-case($reservado)} )
Añada un modelo «Mezcladito» que sea como el «Ibiza» pero con la cilindrada y la velocidad máxima del «León».
copy $mezcladito := //modelo[@nombre = "Ibiza"] modify ( replace value of node $mezcladito/@nombre with "Mezcladito", replace value of node $mezcladito/@id with text {fn:generate-id()}, replace value of node $mezcladito/cilindrada with text {//modelo[@nombre ="León"]/cilindrada}, replace value of node $mezcladito/velmax with text {//modelo[@nombre ="León"]/velmax} ) return insert node $mezcladito after //modelo[last()]
Convertir el número de plazas en un atributo del elemento modelo.
for $modelo in //modelo return ( insert node attribute plazas {$modelo/plazas} into $modelo, delete node $modelo/plazas )
Intercambiar el orden de DNI y nombre.
for $cliente in //cliente return (: Como es sencillo se podría recrear el elemento dni sin necesidad de copiarlo :) copy $dni_c := $cliente/dni modify () return ( delete node $cliente/dni, insert node $dni_c after $cliente/nombre )
Convertir el elemento
<cp>
de la dirección en un atributo de<poblacion>
.for $direccion in //direccion return ( insert node attribute cp {$direccion/cp} into $direccion/poblacion, delete node $direccion/cp )
Mover los coches reservados por un cliente al final del elemento cliente correspondiente y eliminar de ellos el atributo que identifica al comprador ya que no deja de ser necesario.
for $coche in //coche[@reservado][@reservado != "false"] return ( copy $coche_c := $coche modify delete node $coche_c/@reservado return insert node $coche_c into //cliente[@id = $coche/@reservado], delete node $coche )
Tomando el XML del ejercicio sobre facturas genere otro documento XML con las siguientes diferencias:
Divida el elemento
inventario
en tres grupos (elementosgrupo
) en cada uno de los cuales deben encontrarse los productos con un mismo tipo de IVA (superreducido, reducido, normal). Para identificar el tipo de IVA incluya un atributo llamado IVA:<inventario> <grupo iva="superreducido"> <!-- Productos con IVA superreducido --> </grupo> <!-- Resto de grupos --> </inventario>
Como ya no es necesario el atributo iva en los elementos producto, elimínelo.
Añada las facturas de cada cliente, al final del elemento cliente correspondiente y elimine los elementos factura originales. Como no ya no será necesarios los atributos cliente de cada factura, elimínelos también.
xquery version "3.0"; (: Este copy se usa para que la solución no altere el documento de origen, sino una copia en memoria y se genere un documento XML nuevo. Así no es necesario que haya una base de datos. :) copy $facturacion := /facturacion modify ( (: Modificación del inventario :) for $tipo in ("superreducido", "reducido", "normal") let $productos := $facturacion//producto[@iva = $tipo] return ( (: No es posible asegurar el orden de las operaciones, por lo que no podemos asegurar que la eliminación de @iva en $productos se haga antes que su adición a grupo. Por eso hacemos la copia $p. :) insert node element grupo { attribute iva {$tipo}, (: No podemos copiar varios nodos, así que creamos uno que incluya todos los que queremos copiar :) copy $p := <p>{$productos}</p> modify (delete node $p//@iva) return $p/producto (: Estos productos no tiene el atributo iva :) } into $facturacion/inventario, delete node $productos ), (: Traslado de las facturas a cada cliente :) for $cliente in $facturacion//cliente let $facturas := $facturacion/factura[@cliente = $cliente/@id] return ( (: De nuevo, no es posible asegurar el orden de las operaciones, así que necesitamos copiar facturas :) insert node ( copy $f := <f>{$facturas}</f> modify (delete node $f//@cliente) return $f/factura ) into $cliente, delete node $facturas ) ) return $facturacion