XML Ing. Hernán Nina Hanco Temario Estructura de datos XML Esquema de documentos XML Consultas y transformaciones Interfaz de programación de aplicaciones de XML Almacenamiento de datos XML Aplicaciones de XML Introducción XML: Extensible Markup Language Definido por el WWW Consortium (W3C), para la gestión de documentos Derivado de SGML (Standard Generalized Markup Language), pero es mas simple su uso comparado con SGML En particular es útil como formato de datos cuando las aplicaciones se deben comunicar con otra aplicación o integrar información de varias aplicaciones. Los documentos tienen tags o marcas quienes proporcionan información extra acerca de las secciones o partes del documento. Ejm. <titulo> XML </titulo> <diapositiva> Introducción …</diapositiva> Extensible, no como HTML A diferencia de HTML, XML no impone los tags permitidos y se pueden elegir como sea necesario para cada aplicación. Introducción a XML (Continua...) La capacidad de especificar nuevos tags, y crear estructuras de tags anidadas hace que XML sea una excelente opción para intercambiar datos. El uso de XML mas se concentra en el intercambio de datos entre aplicaciones y no es para reemplazar al HTML El uso de Tags crea datos relativamente autodocumentados Ejem. <banco> <cuenta> <numero_cuenta> C-101 </numero_cuenta> <nombre_sucursal> Centro </nombre_sucursal> <saldo> 500 </saldo> </cuenta> <impositor> <numero_cuenta> C-101 </numero_cuenta> <nombre_cliente> Gonzales </nombre_cliente> </impositor> </banco> Motivación del uso de XML Hoy en día el intercambio de datos es critico en las actividades de la sociedad mundial. Ejemplos: Banca: transferencia de fondos Procesamiento de ordenes (especialmente ordenes entre compañías) Datos científicos – Química: ChemML, … – Genética: BSML (Bio-Sequence Markup Language), … El flujo información en papel entre las organizaciones esta siendo reemplazado por el flujo de información electrónica. Cada aplicación en un determinado contexto tiene sus propios conjuntos de estándares para representar información. XML se esta convirtiendo en la base para toda generación de formatos para el intercambio de datos. Motivación del uso de XML (Continua..) Inicialmente la generación de formatos fue basada en textos planos con líneas en el encabezado indicando el significado del campos. Similar a los conceptos de encabezados en correos electrónicos Esta forma no permite generar estructuras anidadas, lenguaje de tipos no estandarizados. Manejo muy cercano a la estructura de bajo nivel de un documento (líneas, espacios, etc.) Cada estándar basado en XML define como se validan los elementos del documento, utilizando: Lenguaje de especificación de tipos XML para especificar la sintaxis DTD (Document Type Descriptors) XML Schema Texto adicional para describir la semántica XML permite definir nuevos tags según se requiera Sin embargo esto puede estar restringido por los DTDs Una amplia variedad de herramientas esta disponible para análisis sintáctico, navegación, consultas a datos de documentos XML. XML comparado con el almacenamiento de datos en un BD Relacional XML puede parecer poco eficiente, puesto que los nombres de las etiquetas se repiten por todo el documento. Sin embargo XML presenta ventajas significativas cuando se usa para el intercambio de datos entre empresas y para almacenar información estructurada en archivos. Los datos XML son autodocumentados debido a la presencia de etiquetas, no como las filas en un esquema relacional. El formato del documento no es rígido: mas etiquetas pueden ser adicionadas. Permite estructuras anidadas Amplia aceptación, no solo en sistemas de bases de datos, sino también en navegadores, herramientas diversas, y aplicaciones. Estructura de datos XML Tag: etiqueta para un sección de datos Element: un elemento es un par de etiquetas de inicio y finalización (<tagname> </tagname>) Los elementos en un documento XML se deben anidar adecuadamente. Anidamiento adecuado … <balance> …. </balance> </account> Anidamiento inadecuado <account> <account> … <balance> …. </account> </balance> Formalmente: Se dice que el texto aparece en el contexto de un elemento si aparece entre la etiqueta de inicio y la etiqueta de finalización de dicho elemento. Los documentos XML deben tener un único elemento raíz que abarque al resto de elementos en el documento. Ejemplos de elementos anidados <banco-1> <cliente> <nombre_cliente> Gonzáles </nombre_cliente> <calle_cliente> Arenal </calle_cliente> <ciudad_cliente> Harrison </ciudad_cliente> <cuenta> <numero_cuenta> C-101 </numero_cuenta> <nombre_sucursal> Centro </nombre_sucursal> <saldo> 900 </saldo> </cuenta> <cuenta> … </cuenta> </cliente> . . </banco-1> Motivación para el uso de anidamiento Las representaciones anidadas se usan ampliamente en las aplicaciones de intercambio de datos XML para evitar las reuniones. Ejemplo: representación de elementos id_cliente, nombre_cliente y direccion_cliente anidado dentro de un elemento orden. Anidamiento no es soportado en bases de datos relacionales Con múltiples ordenes, nombres de clientes y direcciones son almacenadas en forma redundante. La normalización reemplaza las estructuras anidadas en cada orden por las claves foráneas en las tablas que almacenan a nombre_cliente e información de dirección. Anidamiento es soportado en bases de datos orientada a objetos EL anidamiento es apropiado cuando se intercambia datos Aplicaciones externas no tienen acceso directo a datos referenciados por claves externas. Estructuras de datos XML (Continua..) La mescla de texto dentro de los sub- elementos es legal en XML. Ejemplo: <cuenta> esta cuenta casi nunca es usada <numero_cuenta> C-102</numero_cuenta> <nombre_sucursal> Galapagar</nombre_sucursal> <saldo>400 </saldo> </cuenta> Es útil el documento de marcas, pero desalienta la representación de datos. Atributos Los elementos pueden tener atributos <cuenta tipo_cuenta = “corriente” > <numero_cuenta> C-102 </numero_cuenta> <nombre_sucursal> Navacerrada </nombre_sucursal> <saldo> 400 </saldo> </cuenta> Los atributos de un elemento aparecen como pares nombre=valor antes del cierre “>” de una etiqueta. Un elemento puede tener varios atributos, pero cada nombre del atributo puede solo aparecer una vez. <cuenta tipo_cuenta = “corriente” cuota_mensual=“5”> Atributos vs. Subelementos Diferencias entre subelementos y atributos En el contexto de construcción de documentos, es importante la distinción entre elemento y atributo. Los atributos son parte de las marcas, mientras que los subelementos son parte del contenido base del documento. En el contexto de aplicaciones de bases de datos y de intercambio de datos XML, no existe una diferencia clara y puede ser arbitraria. Algunas informaciones puede ser representadas en dos formas: – <cuenta numero_cuenta = “C-101”> …. </cuenta> – <cuenta> <numero_cuenta>C-101</numero_cuenta> … </cuenta> Sugerencia: utilice atributos para identificar a los elementos, y use subelementos para el contenido. Namespaces Los datos XML son intercambiados entre organizaciones Los mismos nombres de etiquetas pueden tener diferente significado en diferentes organizaciones, causando confusión en el intercambio de documentos. Especificando una cadena única como un nombre de elemento evitaría la confusión. Mejor solución: utilizar nombre-unico:nombre-elemento Se pueden evitar el uso de nombres largos y únicos sobre todo el documento, utilizando XML Namespaces (Espacios de nombres) <banco Xmlns:BP=‘http://www.BancoPrincipal.com’> … <BP:sucursal> <BP:nombre_sucursal>Centro</FB:nombre_sucursal> <BP:ciudad_sucursal> Arganzuela </BP:ciudad_sucursal> </BP:sucursal> </banco> Mas sobre la sintaxis de XML Un elemento de la forma <elemento></elemento>, que no contiene subelementos o texto se puede abreviar como <elemento/>, estos elementos pueden tener atributos. <numero_cuenta numero=“A-101” sucursal=“Perryridge” saldo=“200 /> Algunas veces es necesario almacenar valores que contienen sin que se interpreten como etiquetas XML. Para ello, XML permite esta construcción. <![CDATA[<cuenta> … </cuenta>]]> Debido a que el texto <cuenta> esta encerrado en CDATA, se trata como datos de texto normal, no como una etiqueta. CDATA significa datos de tipo carácter. Esquema de los documentos XML Las bases de datos contienen esquemas que se usan para restringir que información se puede almacenar, y especificar los tipos de datos de los valores almacenados. Los documentos XML, se pueden crear de forma predeterminada sin un esquema asociado. Sin embargo, los esquemas son muy importantes para el intercambio de datos XML. De lo contrario, un sitio no podría interpretar automáticamente los datos recibidos de otro sitio. Dos mecanismos para especificar esquemas XML Document Type Definition (DTD).- Ampliamente utilizado XML Schema .- Nuevo, se incrementa su uso Relax NG Document Type Definition (DTD) Los tipos de información presente en un documento XML pueden ser especificados utilizando DTD. Estructura de restricciones DTD de datos XML Que elementos pueden existir Que atributos puede o debe tener un elemento Que subelementos puede o debe existir dentro de cada elemento, y cuantas veces. DTD no restringe los tipos de datos básicos En XML todos los valores son representados como string Sintaxis DTD <!ELEMENT element (subelements-specification) > <!ATTLIST element (attributes) > Especificación de elementos en DTD Los subelementos pueden especificarse como: Nombres de elementos, o #PCDATA (datos analizados de tipo carácter), ejem., datos de tipo texto EMPTY (no tiene elementos, vacio) o ANY (cualquiera) Ejemplo <! ELEMENT deposito (nombre_cliente, numero_cuenta)> <! ELEMENT nombre_cliente (#PCDATA)> <! ELEMENT numero_cuenta (#PCDATA)> Las especificaciones de subelementos puede tener expresiones regulares <!ELEMENT banco ( ( cuenta | cliente | deposito)+)> Notación: “|” - especifica “o” “+” - especifica 1 o mas ocurrencias “*” - especifica 0 o mas ocurrencias “?” - especifica un elemento opcional (es decir, “cero” o “uno”) DTD de un Banco <!DOCTYPE banco [ <!ELEMENT banco ( ( cuenta | cliente | deposito)+)> <!ELEMENT cuenta (numero_cuenta nombre_sucursal saldo)> <! ELEMENT cliente(nombre_cliente calle_cliente ciudad_cliente)> <! ELEMENT deposito (nombre_cliente numero_cuenta)> <! ELEMENT numero_cuenta (#PCDATA)> <! ELEMENT nombre_sucursal (#PCDATA)> <! ELEMENT saldo (#PCDATA)> <! ELEMENT nombre_cliente(#PCDATA)> <! ELEMENT calle_cliente(#PCDATA)> <! ELEMENT ciudad_cliente(#PCDATA)> ]> Especificación de atributos en DTD Especificación de atributos: para cada atributo Nombre Tipo de atributo CDATA ID (identificador) o IDREF (ID referencia) o IDREFS (múltiple IDREFs) Declaración predeterminada obligatorio (#REQUIRED) Tiene un valor por defecto (valor), Ningún valor predeterminado (#IMPLIED) Ejemplos <!ATTLIST cuenta tipo_cuenta CDATA “corriente”> <!ATTLIST cliente id_cliente ID # REQUIRED cuentas IDREFS # REQUIRED > IDs y IDREFs Un elemento puede tener al menos un atributo de tipo ID El valor del atributo ID de cada uno de los elementos en un documento XML debe ser distinto Este valor de atributo ID es un identificador de objeto Un atributo de tipo IDREF debe contener el valor ID de un elemento dentro del mismo documento Un atributo de tipo IDREFS contiene un conjunto de (0 o mas) valores ID. Cada valor ID es el valor ID de un elemento dentro del mismo documento DTD Banco con atributos DTD del banco con atributos de tipo ID y IDREF. <!DOCTYPE banco-2[ <!ELEMENT cuenta (sucursal, saldo)> <!ATTLIST cuenta numero_cuenta ID # REQUIRED titulares IDREFS # REQUIRED> <!ELEMENT cliente(nombre_cliente, calle_cliente, ciudad_cliente)> <!ATTLIST cliente id_cliente cuentas ]> ID # REQUIRED IDREFS # REQUIRED> … declaraciones para sucursal, saldo, nombre_cliente, calle_cliente y ciudad_cliente Datos XML con atributos ID e IDREFs <banco-2> <cuenta numero_cuenta=“C-401” titulares=“C100 C102”> <nombre_sucursal> centro </nombre_sucursal> <saldo> 500 </saldo> </cuenta> <cliente id_cliente=“C100” cuentas=“C-401”> <nombre_cliente> Juan </nombre_cliente> <calle_cliente> Olivos </calle_cliente> <ciudad_cliente> Cusco</ciudad_cliente> </cliente> <cliente id_cliente=“C102” cuentas=“C-401 C-402”> <nombre_cliente> Mary </nombre_cliente> <calle_cliente> Jose olaya </calle_cliente> <ciudad_cliente> Cusco </ciudad_cliente> </cliente> </banco-2> Limitaciones de los DTDs No se puede declarar el tipo de cada elemento y de cada atributo de texto Todos los valores son cadenas, no es posible declarar enteros, reales, etc. Es difícil usar el mecanismo DTD para especificar conjuntos desordenados de subelementos El orden es rara vez importante para el intercambio de datos Hay una falta de tipos en IDs e IDREFs. Por ello no hay forma de especificar el tipo de elemento al cual se debería referir un atributo IDREF o IDREFS. Por tanto DTD no evita que el atributo “titulares” de un elemento cuenta se refiere a otras cuentas, aunque esto no tenga sentido El atributo titulares debería restringir la referencia a los elementos clientes XML Schema XML Schema es un lenguaje de esquema sofisticado e intenta reparar las deficiencias de DTDs. Soporta: Declarar tipos de los valores: string, integer, decimal, date y boolean Tipos complejos como secuencias Crear tipos definidos por el usuario Restricciones de clave externa, herencia y valores únicos Las propias definiciones en XML schema se especifican en sintaxis XML, no como DTDs XML Schema es integrado con namespaces Pero: XML Schema es significativamente mas complicado comparado a los DTDs. Versión XML Schema para el DTD del Banco <xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema> <xs:element name=“Banco” type=“TipoBanco”/> <xs:element name=“cuenta”> <xs:complexType> <xs:sequence> <xs:element name=“numero_cuenta” type=“xs:string”/> <xs:element name=“nombre_sucursal” type=“xs:string”/> <xs:element name=“saldo” type=“xs:decimal”/> </xs:squence> </xs:complexType> </xs:element> ….. definición de cliente e impositor <xs:complexType name=“TipoBanco”> <xs:squence> <xs:element ref=“cuenta” minOccurs=“0” maxOccurs=“unbounded”/> <xs:element ref=“cliente” minOccurs=“0” maxOccurs=“unbounded”/> <xs:element ref=“impositor” minOccurs=“0” maxOccurs=“unbounded”/> </xs:sequence> </xs:complexType> </xs:schema> Consulta y transformación de datos XML Transformar datos de un esquema XML a otro Consultas sobre datos XML Las operaciones de transformación y consulta pueden combinarse en una única herramienta. Estándares de Lenguajes de consulta/transformación XML XPath: Lenguaje simple que consiste de expresiones de rutas de acceso XSLT: Lenguaje simple diseñado para transformar de XML a XML y XML a HTML XQuery: Un lenguaje de consulta XML con un conjunto rico de características Modelo de árbol de datos XML Los lenguajes de consultas y transformación son basados en un modelo de árbol de datos XML. Un documento XML es modelado como un árbol, con nodos correspondiente a los elementos y atributos Los nodos tienen nodos hijos, quienes pueden ser atributos o subelementos Los texto en un elemento es modelado como un nodo hijo texto de un elemento Los hijos de un nodo son ordenados de acuerdo a su orden en el documento XML Los nodos de elemento y atributo(excepto el nodo raíz) tienen un simple padre el cual es un nodo de un elemento XPath XPath es usado para localizar (select) partes de documentos usando path expressions(Expresiones de Path) Un path expression es una secuencia de pasos de ubicación separados por “/” (pensar en nombres de archivos dentro de una jerarquía de carpetas) El resultado de la path expression es un conjunto de nodos Ejemplo: la expresion Path /banco-2/cliente/nombre_cliente devolverá estos elementos: <nombre_cliente>Joe</nombre_cliente> <nombre_cliente>Mary<nombre_cliente> Ejemplo: /banco-2/cliente/nombre_cliente/text( ) devolverá los mismos nombres, pero sin etiquetas que lo rodean. XPath (Continuación) La barra inicial “/” indica la raíz del documento Las expresiones Path son evaluadas de izquierda a derecha Cada paso opera sobre el conjunto de instancias producidas por el paso previo Los predicados de selección pueden seguir cualquier paso en una ruta y se escriben entre corchetes. Por ejemplo. /banco-2/cuenta[saldo > 400] Devuelve elementos de cuenta con saldo superior a 400 /banco-2/cuenta[saldo] devuelve elementos de cuenta que contiene un subelemento saldo Se puede acceder al valor de atributos utilizando “@” Ejemplo. /banco-2/cuenta[saldo > 400]/@numero_cuenta Devuelve el numero de cuenta de las cuentas con saldo > 400 De forma predeterminada no se siguen los vínculos IDREF Funciones en XPath XPath provee varias funciones La función count() al final de una ruta de acceso cuenta el numero de elementos en el conjunto generado por la ruta de acceso Ejemplo /banco-2/cuenta[count(./cliente) > 2] – Devuelve las cuentas con más de dos clientes Conectivas lógicas and y or y función not() puede ser usado en los predicados IDREFs pueden ser referenciados usando las función id() id() se puede incluso aplicar a conjuntos de referencias o incluso a cadenas que contengan referencias múltiples separadas por espacio vacios. Tales como IDREFS. Ejemplo /banco-2/cuenta/id(@titular) Devuelve todos los clientes referenciados desde el atributo titular de los elementos cuenta Mas características de XPath Operador “|” usado para implementar unión /banco-2/cuenta/id(@titular) | /banco-2/prestamo/id(@prestatario) Proporciona los clientes con cuentas o prestamos Sin embargo, “|” no se puede anidar dentro de otros operadores. “//” puede saltar varios niveles de nodos /banco-2//nombre_cliente Encuentra cualquier elemento nombre_cliente en cualquier lugar por debajo del elemento /banco-2, independientemente del elemento en el que este contenido. Cada paso en la ruta no selecciona lo hijos de los nodos del conjunto actual de nodos. “//”, es una forma abreviada de especificar “todos los descendientes” “..” especifica el padre. doc(“banco.xml”) devuelve la raíz de un documento XML banco.xml XQuery XQuery es un lenguaje de consulta para datos XML de propósito general Actualmente esta siendo estandarizado por la World Wide Web Consortium (W3C) XQuery es derivado de Quilt query language, y otros dos lenguajes, XQL y XML-QL XQuery utiliza expresiones FLWOR For … Let … Where … Order by …Result … sintaxis for SQL from where SQL where order by SQL order by result SQL select let permite variables temporales, y no tiene equivalencia en SQL Sintaxis FLWOR en XQuery La clausula For proporciona una serie de variables cuyos valores son los resultados de expresiones XPath Expresión FLWOR sencilla en XQuery Devuelve los números de cuenta de las cuentas corrientes Busca todas las cuentas con saldo > 400, con cada resultado encerrado en etiquetas <numero_cuenta> .. </numero_cuenta> for $x in /banco-2/cuenta let $numecuenta := $x/@numero_cuenta where $x/saldo > 400 return <numero_cuenta> { $numcuenta } </numero_cuenta> Los Items en la clausula return son textos XML excepto los textos encerrados entre {}, que se evalúan como expresiones La clausula Let es opcional en la consulta, la selección puede ser hecha en XPath: for $x in /banco-2/cuenta[saldo>400] return <numero_cuenta> { $x/@numero_cuenta } </numero_cuenta> Reuniones o Joins Reuniones son especificadas de manera muy similar a SQL for $a in /banco/cuenta, $c in /banco/cliente, $d in /banco/deposito where $a/numero_cuenta = $d/numero_cuenta and $c/numero_cuenta = $d/numero_cuenta return <cuenta_cliente> { $c $a } </cuenta_cliente> La misma consulta se puede expresar con las selecciones especificadas como selecciones XPath: for $a in /banco/cuenta $c in /banco/cliente $d in /banco/deposito[ numero_cuenta = $a/numero_cuenta and nombre_cliente = $c/nombre_cliente] return <cuenta_cliente> { $c $a } </cuenta_cliente> Consultas anidadas En la clausula return se pueden anidar como se muestra la siguiente consulta. <banco-1> { for $c in /banco/cliente return <cliente> { $c/* } { for $d in /banco/deposito[nombre_cliente = $c/nombre_cliente], $a in /banco/cuenta[numero_cuenta=$d/numero_cuenta] return $a } </cliente> } </banco-1> $c/* denota todos los hijos del nodo ligados a la variable $c $c/text() proporciona el contenido textual de un elemento, sin las etiquetas. Ordenación de resultados en XQuery En XQuery los resultados se pueden ordenar si se incluye una clausula order by Ejemplo: para retornar clientes ordenados pos nombre for $c in /banco/cliente order by $c/nombre_cliente return <cliente> { $c/* } </cliente> Usar order by $c/customer_name descending para ordenar en forma descendente La ordenación se puede realizar en varios niveles de anidamiento. Por ejemplo, se puede obtener una representación anidada de la información bancaria ordenada según el nombre del cliente, con las cuentas de cada cliente ordenadas según el número de cuenta: <banco-1> { for $c in /banco/cliente order by $c/nombre_cliente return <cliente> { $c/* } { for $d in /banco/deposito[cliente_nombre=$c/nombre_cliente], $a in /banco/cuenta[numero_cuenta=$d/numero_cuenta] } order by $a/numero_cuenta return <cuenta> $a/* </cuenta> </cliente> } </banco-1> Funciones y otras características de XQuery Funciones definidas por el usuario. La siguiente consulta devuelve la lista de todos los saldos de un cliente con un nombre especificado. function saldos(xs:string $c) returns list(xs:decimal*) { for $d in /banco/deposito[nombre_cliente = $c], $a in /banco/cuenta[numero_cuenta= $d/numero_cuenta] return $a/saldo } La especificación de tipo de los argumentos de la función y de los valores es opcional. Los tipos * (como un decimal*) indica una secuencia de valores de este tipo La cuantificacion existencial y universal que se pueden utilizar en predicados de la clausula where some $e in path satisfies P every $e in path satisfies P (donde path y P es un predicado que puede usar $e) XQuery también soporta clausulas If-then-else XSLT Un stylesheet (hoja de estilo) es una representación de las opciones de formato para un documento, normalmente almacenado fuera del contenido del documento mismo. Ejemplo el HTML. XML Stylesheet Language (XSL) fue originalmente diseñado para generar documentos HTML desde XML XSLT es un lenguaje de transformación de propósito general Can transformar XML a XML, y XML a HTML Las transformaciones XSLT se expresan como una serie de reglas recursivas, denominadas plantillas En su forma básica las plantillas permiten la selección de nodos en un árbol XML mediante una expresión XPath Plantillas XSLT Ejemplo de una plantilla XSLT con parte match(coincidencia) y select(selección) <xsl:template match=“/banco-2/cliente”> <xsl:value-of select=“nombre_cliente”/> </xsl:template> <xsl:template match=“*”/> La Instrucción xsl:template match contiene una expresión XPath La plantilla busca coincidencias de elementos clientes que aparecen como hijos del elemento raíz banco-2. La instrucción xls:value-of encerrada en la instrucción de coicidencias devuelve valores de los nodos en el resultado de la expresión XPath Ejercicios Hallar la DTD para una representación XML del siguiente esquema relacional anidado: Emp = (nombree, ConjuntoHijos setOf(Hijos), ConjuntoMaterias setOf(Materias)) Hijos = (nombre, cumpleaños) Cumpleaños = (día, mes, año) Materias = (tipo, ConjuntoExamenes setOf(Exámenes)) Exámenes = (año, ciudad) Solución <!DOCTYPE BD [ <!ELEMENT Emp (nombree, Hijos*, Materias*)> <!ELEMENT Hijos (nombre, Cumpleaños)> <!ELEMENT Cumpleaños (día, mes, año)> <!ELEMENT Materias (tipo, exámenes+)> <!ELEMENT exámenes (año, ciudad)> <!ELEMENT nombree( #PCDATA )> <!ELEMENT nombre( #PCDATA )> <!ELEMENT dia( #PCDATA )> <!ELEMENT mes( #PCDATA )> <!ELEMENT año( #PCDATA )> <!ELEMENT tipo( #PCDATA )> <!ELEMENT ciudad( #PCDATA )> ]> Ejercicio 2 Escribir una consulta en Xpath sobre el DTD anterior para listar todo los tipos de materia de Emp Solución 2 /bd/Emp/materias/tipo Ejercicio 3 Escribir una consulta XQuery en la representación XML de la diapositiva 4 para encontrar el saldo total de cada sucursal teniendo en cuenta todas las cuentas. Solución ejercicio 3 for $b in distinct (/banco/cuenta/nombre_sucursal) return <total_sucursal> <nombre_sucursal> $b/text() </ nombre_sucursal > let $s := sum (/banco/cuenta[nombre_sucursal=$b]/saldo) return <total-balance> $s </total-balance> </ total_sucursal >