Consultando Documentos XML com XQUERY Vânia Maria Ponte Vidal [email protected] Por que uma linguagem de Consulta para XML? Consultar bases de dados XML tornou-se necessário dado que grandes quantidades de dados estão sendo armazenados utilizando XML. Dados XML são diferentes dos dados de bancos de dados relacionais ou orientados a objetos pois os dados XML não seguem uma estrutura rígida. Devido a flexibilidade da XML, linguagens de consultas convencionais não são adequadas para especificar consultas em documentos XML Linguagens de Consulta para XML LOREL: foi projetada inicialmente para consultar dados semi-estruturados e recentemente foi estendida para manipulação de dados XML. É uma linguagem baseada em OQL. XML-QL: estende linguagem SQL com uma cláusula explícita CONSTRUCT que permite a construção de documentos como resultado de consulta XML-GL: linguagem de consulta gráfica que tem como base uma representação em grafos de documentos XML e DTDs Linguagens de Consulta para XML XSL (Extensible Stylesheet Language): utiliza a linguagem XPath para selecionar os elementos a serem processados e para geração de textos XQL: pode ser considerada uma extensão da sintaxe da XSL e foi projetada com o objetivo de ser sintaticamente mais simples e compacta, entretanto com o poder de expressão reduzido XQuery XML Query Language Proposta pela W3C e agrega características de diversas outras linguagens de consulta para XML, bem como SQL e OQL É uma linguagem funcional na qual a consulta é representada como uma expressão Utiliza o conceito de expressões de caminho para navegar em árvores Xquery é flexível o suficiente para consultar vários tipos de fontes de informação XML incluindo bancos de dados e documentos XQuery - Conceitos Uma consulta em XQuery é uma expressão que: Lê um número de documentos XML ou fragmentos de documentos XML Retorna uma seqüência de fragmentos XML bemformados Expressões XQuery podem ser: Expressões de caminho Construtores de elementos Expressões FLWR Expressões condicionais Expressões com quantificadores XQuery – Expressões de Caminho Consiste de uma série de passos. Cada passo pode aplicar um ou mais predicados para eliminar nós que não satisfazem uma determinada condição Uma expressão de caminho pode começar com uma expressão que identifica um nó específico, como a função document (string), que retorna o nó raiz de um dado documento Uma expressão de caminho também pode começar com “/” ou “//”, que representa um nó raiz implícito, determinado pelo ambiente no qual a consulta está sendo executada. Expressões de Caminho Exemplo Q1: Obtenha todas as figuras cujo título é “Fig1” doc capitulo * parte * figura titulo numero procura um elemento figura em qualquer profundidade depois do elemento doc document(“livro.xml”) / doc // figura[titulo= “Fig1”] A função document lê um arquivo XML e retorna o nó raiz do documento Expressões FLWR Consiste de uma seqüência de um ou mais cláusulas FOR e/ou LET, seguidas por um WHERE opcional e terminada por um RETURN FLWR = FOR-LET-WHERE-RETURN FOR e LET: associam valores a uma ou mais variáveis WHERE: expressão condicional RESULT: retorna o resultado Expressões FLWR - Exemplo Q2: Obtenha os títulos dos livros cujo primeiro nome do autor é “José” livraria livros livro* autor pri_nome sobrenome titulo FOR $l IN document(“livraria.xml”)//livro WHERE $l/autor/pri_nome = “José” RETURN $l/titulo FOR $l IN document(“livraria.xml”)//livro[autor/pri_nome = “José”] RETURN $l/titulo Construção de Elementos Q3:Gerar documento XML cuja raiz é o elemento livros o qual contém todos os títulos dos livros cujo autor tem como primeiro nome “José” <livros> { FOR $l IN document(“livraria.xml”)//livro WHERE $l/autor/pri_nome = “José” RETURN $l/titulo } </livros> constrói um elemento livros FLWR - Exemplo Q4: Obter o ano e o título de todos os livros publicados pela editora Addison-Wesley depois de 1991. livraria livro* titulo ano autor+ pri_nome sobrenome editor+ pri_nome sobrenome associação editora preço <livraria> Expressão de caminho { FOR $l IN document(doc.xml)/livraria/livro WHERE $l/editora = “Addison-Wesley” and $l/@ano > 1991 @ é utilizado para acessar o valor do RETURN atributo <livro ano=“{$livro/@ano}”> {$l/titulo} </livro> } </livraria> FLWR - Exemplo Q5: Criar elemento resultado contendo conjunto de elementos livroWesley (os livros publicados pela Addison-Wesley ), o qual contém o título e autor do livro. livraria livro* titulo ano autor+ pri_nome sobrenome editor+ pri_nome sobrenome associação editora preço <resultado> { FOR $l in document(“doc.xml")/livraria/livro, WHERE $l/editora = “Addison-Wesley” RETURN < livroWesley > {($l/titulo, $l/autor )} </livroWesley > } </resultado> FLWR - Exemplo Q6: criar elemento listaSeções o qual contém, para cada elemento seção de livro1.xml, um elemento seção contendo dois atributos título e figcont cujo valor é o número de figuras contidas na seção. livro <listaSeções> titulo { autor FOR $s in document(“livro1.xml")//seção seção + RETURN @id @dificuldade <seção titulo="{ $s/titulo/text() }" titulo figcont="{ count($s/figura )}”/> figura * } titulo caminho </listaSeções > livro1.xml retorna apenas o conteúdo do elemento (sem as tags) Ordenando Algumas vezes é necessário controlar a ordem dos elementos na sequência Uma seqüência pode ser ordenada utilizando a cláusula SORTBY, que pode conter uma ou mais expressões ordenadas Cada expressão ordenada pode vir seguida de uma palavra chave Ascending (default) descending Ordenando - Exemplo Q7: Obtenha o título e o ano de todos os livros publicados pela editora Addison-Wesley depois de 1991 e em ordem alfabética livraria livro* titulo ano autor+ pri_nome sobrenome editor+ pri_nome sobrenome associação editora preço <livraria> { FOR $l IN document(doc.xml)/livraria/livro WHERE $l/editora = “Addison-Wesley” and $l/@ano > 1991 RETURN <livro ano=“{$livro/@ano}”> {$l/titulo} </livro> SORT BY (titulo) } </livraria> Expressões Condicionais XQuery suporta expressões condicionais baseadas em if, then, else Expressões condicionais são úteis quando a estrutura da informação a ser retornada depende de alguma condição As expressões condicionais podem ser aninhadas e podem ser usadas em qualquer lugar onde um valor é esperado Expressões Condicionais - Exemplo Q8: Gerar elemento contendo o título e os dois primeiros autores dos livros. Se o livro tem outros autores então acrescentar o elemento vazio <outros/> <livros> livraria { FOR $l IN document(“Livraria.xml”)//livro livro* RETURN titulo Retorna a posição <livro> ano do elemento { ($l/titulo, autor+ FOR $a in $l/autor[position( )<= 2] pri_nome RETURN $a , sobrenome expressão condicional IF (count($l/autor) >2) editor+ THEN <outros/> pri_nome elemento vazio ELSE ( ))} sobrenome </livro> associação } editora </livros> preço Expressões com Quantificadores Ocasionalmente é necessário testar se algum elemento ou todos elementos de uma coleção satisfaz uma condição Para isso utilizamos o quantificador existencial (some) e o quantificador universal (every) Expressões com Quantificadores Q9: Gerar elemento contendo para cada autor, o nome e os títulos de todos os livros do autor. Estes últimos, devem estar agrupados dentro de um elemento livrosDoAutor. Retorna somente valores distintos livraria livro* titulo ano autor+ pri_nome sobrenome editor+ pri_nome sobrenome associação editora preço <resultado> {FOR $a IN distinctvalues(document(“livraria.xml”)//autor) RETURN deep-equal( ) testa se dois nós tem a mesma estrutura <autor> e os mesmos valores {($a, <livrosDoAutor> {FOR $l IN document(“livraria.xml”)/livraria/livro WHERE some $la IN $l/autor satisfies deep-equal($la,$a) RETURN $l/titulo) } <livrosDoAutor> } </autor> </resultado> Expressões com Quantificadores livraria Q10 :Obtenha os títulos dos livros que tem “ótimo” em todos os comentários livro titulo autor pri_nome sobrenome comentario * <resultado> {for $l in //livro where every $c in $l/comentario contains($c, “ótimo”) return $l/titulo quantificador universal } </resultado> Funções Funções pré-definidas que podemos utilizar nas consultas XQuery (Xpath) concat Concatena duas ou mais strings starts-with Indica se o valor de uma string começa com o caracter do valor da outra string ends-with Indica se o valor de uma string termina com o caracter do valor da outra string contains Indica se o valor de uma string contém caracteres iguais ao valor da outra string string-length Retorna o tamanho da string substring – before Retorna os caracteres de uma string que precedem os caracteres que são iguais aos outra string substring – after Retorna os caracteres de uma string que que vem depois dos caracteres que são iguais aos outra string Funções - Exemplo Q11: Para cada livro contendo algum elemento cuja “label” termina com a string “or” e cujo conteúdo contém a string “José”, faça: - Retorne o título do livro e o elemento encontrado livraria livro* titulo ano autor+ pri_nome sobrenome editor+ pri_nome sobrenome associação editora preço * pega qualquer sub-elemento Procura a string no nó atual for $l in document(“www.bn.com/livraria.xml”)//livro let $e:= $l/* [contains(string(.),”José”) and ends-with(local-name(.),”or”)] where exists($e) Indica que é o nome do elemento e não o return conteúdo do elemento <book> { $l/titulo } { $e } </book> Funções - Exemplo Q12:Liste todos os elementos seção preservando seus atributos e hierarquia. Dentro de cada seção coloque o título da seção e um elemento com o número de figuras contidos imediatamente naquela seção define function resumo_seção(element $s) returns element livro { <section> titulo { ($s/@* , * Obtém todos os atributos de seção autor $s/title , seção + <numfig>{ count($s/figura) }</numfig> , for $ss in $s/seção @id return resumo_seção($ss) )} @dificuldade </section> } titulo -----------------------------------------------------------------figura * <resultado> titulo { for $s in document(“livro.xml")/livro/seção caminho return resumo_seção($s)} seção * </resultado> XQuery Uma consulta em XQuery é uma expressão que: Lê um número de documentos XML ou fragmentos de documentos XML Retorna uma seqüência de fragmentos XML bemformados Expressões XQuery podem ser: Expressões de caminho Construtores de elementos Expressões FLWR Expressões condicionais Expressões com quantificadores ESTUDO DE CASO I Elemento Raiz livraria livro autor autor @ISBN titulo editora preço autor 1234 Inside New 100,00 [email protected] XML Riders autor [email protected] email [email protected] nome email nome Steven [email protected] Holzner (*) Vide XML Schema em arquivo separado XQuery Expressões FLWR – Exemplo (1) - Obtenha ISBN, título e editora do livro cujo título é “Inside XML”. <livroXML> {FOR $q IN document(“liv.xml” ) / livraria / livro[titulo =“Inside XML”] RETURN <livro> { ($q/@ISBN,$q/titulo,$q/editora) } </livro> } </ livroXML > XQuery Expressões FLWR – Exemplo (2) - Obtenha o titulo dos livros de autoria de Steven. <livrosSteven> { FOR $q IN document("Livraria.xml")/livraria/livro LET $p := document("Livraria.xml")/livraria/autor[nome="Steven"] WHERE $q/autor = $p/email RETURN $q/titulo } </livrosSteven>