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:

  1. En el ejercicio sobre facturas:

    1. 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"
      
    2. Añada al final de todos los clientes un elemento que sea <solvente />.

      for $cliente in //cliente
      return
         insert node <solvente/> into $cliente
      
    3. Elimine todos los elementos que acaba de añadir,

      delete node //cliente/solvente
      
    4. 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"}
      
    5. Elimine los descuentos de todas las facturas.

      delete node //factura/@descuento
      
    6. Añada a la factura «f01» un descuento del 15%.

      insert node attribute descuento {15} into //factura[@codigo="f01"]
      
    7. Aumente en +5% el descuento a todas las facturas.

      for $descuento in //factura/@descuento
      return
         replace node $descuento with attribute {name($descuento)} {$descuento + 5}
      
    8. 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]
      
    9. 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
      
    10. 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
      
  2. En el ejercicio 8 sobre concesionarios y clientes:

    1. Cambiar la marca del concesionario por «Dacia».

      replace node /concesionario/@marca with attribute marca {"Dacia"}
      
    2. Limite la velocidad máxima a 180.

      for $vel in //velmax
      where $vel > 180
      return
         replace value of node $vel with text {180}
      
    3. 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
      
    4. 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)},
      
    5. 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)}
         )
      
    6. 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()]
      
    7. 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
         )
      
    8. 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
         )
      
    9. 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
         )
      
    10. 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
         )
      
  3. Tomando el XML del ejercicio sobre facturas genere otro documento XML con las siguientes diferencias:

    • Divida el elemento inventario en tres grupos (elementos grupo) 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