XQuery Helena Galhardas DEI IST Agenda XPath – exercício XQuery Exemplo <bib> <book> <publisher> Addison-Wesley </publisher> <author> Serge Abiteboul </author> <author> <first-name> Rick </first-name> <last-name> Hull </last-name> </author> <author> Victor Vianu </author> <title> Foundations of Databases </title> <year> 1995 </year> </book> <book price=“55”> <publisher> Freeman </publisher> <author> Jeffrey D. Ullman </author> <title> Principles of Database and Knowledge Base Systems </title> <year> 1998 </year> </book> </bib> Modelo de dados para XPath A raíz bib book publisher Addison-Wesley O elemento raíz book author . . . . Serge Abiteboul Idêntico ao modelo de dados de XQuery Expressões simples /bib/book/year Resultado: <year> 1995 </year> <year> 1998 </year> /bib/paper/year Resultado: empty (não existem artigos) Sumário dos exemplos bib elemento bib * qualquer elemento / root /bib bib debaixo de root bib/paper paper debaixo de bib bib//paper paper bebaixo de bib, a qq profundidade //paper paper a qualquer profundidade paper|book um paper ou um book @price atributo price bib/book/@price atributo price em book, em bib db/book[@price] books que têm um atributo price db/book[@price=’10’] books com price igual a 10 Exercício Considere um documento XML d que representa uma colecção de CDs. Assuma que o documento é válido no que diz respeito à seguinte DTD: <!ELEMENT CDlist ((CD)+)> <!ELEMENT CD (composer, (performance)+, publisher, (length)?)> <!ELEMENT performance (composition, (soloist)?, (orchestra, conductor)?)> <!ELEMENT composer (#PCDATA)> <!ELEMENT publisher (#PCDATA)> <!ELEMENT length (#PCDATA)> <!ELEMENT composition (#PCDATA)> <!ELEMENT soloist (#PCDATA)> <!ELEMENT orchestra (#PCDATA)> <!ELEMENT conductor (#PCDATA)> Quais as expressões XPath que retornam o seguinte de d, assumindo que o contexto inicial é o elemento CDlist: Todas as composições Todas as composições envolvendo um solista Todas as execuções com uma orquesta mas sem solista Todos os solistas que tocaram com a London Symphony Orchestra num CD publicado pela Deutsche Grammophon Todos os CDs que têm execuções pela London Symphony Orchestra Todas as composições: CD/performance/composition Todas as composições envolvendo um solista: CD/performance[soloist]/composition Todas as execuções com uma orquestra mas sem solista: CD/performance[orchestra and not(soloist)] Todos os solistas que tocaram com a London Symphony Orchestra num CD publicado pela Deutsche Grammophon CD[publisher="Deutsche Grammophon"]/performance [orchestra="London Symphony Orchestra"]/soloist Todos os CDs com execuções pela London Symphony Orchestra CD[performance[orchestra="London Symphony Orchestra"]] XQuery Baseado em Quilt: que é um apanhado de funcionalidades de outras linguagens (por ex., XMLQL) Desenhado para obedecer aos requisitos identificados pelo W3C Query Working Group Linguagem funcional na qual uma interrogação é uma expressão. Expressões podem estar completamente aninhadas Entrada e saída de uma interrogação são documentos XML, fragmentos de docs XML ou colecções de docs XML. Estes podem ser modelados como uma floresta ordenada de nós. Principios do XQuery (1) Fecho Composição Definir um modelo de dados e um conjunto de operadores que é fechado sobre o modelo XQuery agrupa vários tipos de expressões Cada expressão pode ser avaliada sem efeitos secundários As expressões podem ser compostas com generalidade Obedece ao esquema Utilizar XML Schema Tipos pré-definidos Principios do XQuery (2) Compatível com Xpath Complitude Adopta XPath como um sub-conjunto sintático Compatível com XPath 1.0 e 2.0 Tão bom como o modelo relacional Não existia nenhum standard para as linguagens hierárquicas Funções recursivas Conciso e simples de expressar Principios do XQuery (2) Compatível com Xpath Complitude Adopta XPath como um sub-conjunto sintático Compatível com XPath 1.0 e 2.0 Tão bom como o modelo relacional Não existia nenhum standard para as linguagens hierárquicas Funções recursivas Conciso e simples de expressar Principios do XQuery (3) Deve permitir uma análise estática Fase opcional de análise estática antes de cada execução de interrogação Regras de inferência de tipo baseadas em XML Schema Permite a detecção de erros durante a compilação Facilita a optimização Expressões de caminho em XML Baseado na sintaxe abreviada de XPath Exemplo: quais as figuras com legenda "Tiger" no segundo capítulo do documento com nome zoo.xml: document("zoo.xml")/chapter[2] //figure[caption="Tiger"] Três passos de localização: document() encontra o nó raiz do documento chapter[2] encontra o elemento “2º capítulo” que é filho da raíz. //figure[caption="Tiger"] encontra os elementos figure que ocorrem em qualquer sítio dentro do capítulo, só devolve aqueles que satisfazem o predicado Como seguir referências ID? Operador de “desreferênciação” –> semelhante ao id() do XPath Usado para seguir um atributo do tipo IDREF Retorna os elementos referenciados pelo atributo Exemplo: quais as legendas de figuras que são referenciadas por elementos figref (usando o atributo refid) no capítulo de zoo.xml com título "Tigers": document("zoo.xml")/chapter[title="Tigers"] //figref/@refid->/caption Bases de dados relacionais S(sno, sname) - Supplier P(pno, descrip) - Parts SP(sno, pno, price) – Supplies Part Exemplo de um esquema relacional Interrogação select-project do SQL Quais os números das peças cuja descrição contém : “motor”? Select pno From P Where descrip like ‘motor’ Interrogação join SQL Quais os nomes dos fornecedores e a descrição das peças que eles fornecem? Select sname, descrip From S, P, SP Where S.sno = SP.sno and P.pno = SP.pno Equivalente a: Select sname, descrip From (S inner join SP on S.sno = SP.sno) Inner join P on p.pno = SP.pno Dados relacionais vistos como dados em XML Relacional: S(sno, sname) - Supplier P(pno, descrip) - Parts SP(sno, pno, price) – Supplies Part XML: <S> <s-tuple> <sno> <sname> <P> <p-tuple> <pno> <descrip> .... Interrogação select-project XQuery Quais os números cujas descrições contêm “motor”? For $p in document(“p.xml”)//p_tuple Where contains($p/descrip, “motor”) Return $p/pno for...where...return é análogo a from... where... select $p é uma variável que itera sobre p_tuples Contains() é um predicado análogo a LIKE Interrogação join XQuery Quais os nomes dos fornecedores e a descrição dos produtos que eles fornecem? FOR $sp IN document("sp.xml")//sp_tuple, $p IN document("p.xml")//p_tuple[pno=$sp/pno], $s IN document("s.xml")//s_tuple[sno=$sp/sno] RETURN <sp_pair> $s/sname, $p/descrip </sp_pair> $p itera sobre os p-tuples que contêm elementos pnoque correspondem a elementos pno em sp-tuples $s itera sobre s-tuples que contêm elementos sno que correspondem a elementos sno em sp_tuples Sp_pair é um elemento constructor O que é uma interrogação XQuery? É uma expressão que: Lê uma sequência de fragmentos de XML ou de valores atómicos Retorna uma sequência de fragmentos de XML ou de valores atómicos Formas principais que uma expressão XQuery pode tomar: Expressões de caminho Constructores Expressões FLWOR Expressões de listas Condições Expressões quantificadas Expressões de tipos de dados Funções Relembrando o exemplo <bib> <book> <publisher> Addison-Wesley </publisher> <author> Serge Abiteboul </author> <author> <first-name> Rick </first-name> <last-name> Hull </last-name> </author> <author> Victor Vianu </author> <title> Foundations of Databases </title> <year> 1995 </year> </book> <book price=“55”> <publisher> Freeman </publisher> <author> Jeffrey D. Ullman </author> <title> Principles of Database and Knowledge Base Systems </title> <year> 1998 </year> </book> </bib> Expressões FLWOR (“Flower”) FOR ... LET... FOR... LET... WHERE... ORDER BY… RETURN... Sumário das expressões FLWOR Exemplo simples Quais os títulos dos livros publicados depois de 1995: FOR $x IN doc("bib.xml")/bib/book WHERE $x/@year > 1995 RETURN $x/title Resultado: <title> abc </title> <title> def </title> <title> ghi </title> Distinct Para cada autor de um livro editado pela Morgan Kaufmann, listar todos os livros por ele publicados: FOR $a IN distinct(doc("bib.xml") /bib/book[publisher=“Morgan Kaufmann”]/author) RETURN <result> { $a, FOR $t IN /bib/book[author=$a]/title RETURN $t } </result> distinct = função que elimina duplicados Resultado <result> <author>Jones</author> <title> abc </title> <title> def </title> </result> <result> <author> Smith </author> <title> ghi </title> </result> Cláusulas FOR e LET FOR $x in expr -- associa $x a cada valor da lista dada por expr LET $x = expr -- associa $x à lista completa dada por expr Útil para sub-expressões comuns e agregações FOR versus LET FOR Associa variáveis de nó (node variables) iteração LET Associa variáveis de colecção (collection variables) um valor FOR versus LET (exemplos) FOR $x IN doc("bib.xml")/bib/book RETURN <result> { $x } </result> Retorna: <result> <book>...</book></result> <result> <book>...</book></result> <result> <book>...</book></result> ... LET $x IN doc("bib.xml")/bib/book RETURN <result>{ $x } </result> Retorna: <result> <book>...</book> <book>...</book> <book>...</book> ... </result> Exemplo 1: FOR e LET <big_publishers> FOR $p IN distinct(doc("bib.xml")//publisher) LET $b := doc("bib.xml")/book[publisher = $p] WHERE count($b) > 100 RETURN $p </big_publishers> count = função de agregação que retorna o número de elementos Exemplo 2: FOR e LET Quais os livros cujo preço é maior do que a média dos preços: LET $a=avg(doc("bib.xml")/bib/book/price) FOR $b in document("bib.xml")/bib/book WHERE $b/price > $a RETURN $b Junções <reviews> <entry> <title>TCP/IP Illustrated</title> <rating>5</rating> <remarks>Excellent technical content. Not much plot.</remarks> </entry> </reviews> for $t in doc("books.xml")//title, $e in doc("reviews.xml")//entry where $t = $e/title return <review>{ $t, $e/remarks }</review> Ordenação em XQuery Listar os nomes dos livros por ordem alfabética FOR $t IN doc("books.xml")//title ORDER BY $t RETURN $t Diferentes especificações de ordem Quais os autores ordenados por ordem inversa do último nome e depois pelo primeiro nome for $a in doc("books.xml")//author order by $a/last descending, $a/first descending return $a Constructores Para construir um novo elemento com um nome conhecido e um conteúdo, usar a sintaxe XML-like: <book isbn = "12345"> <title>Huckleberry Finn</title> </book> Se o conteúdo do elemento ou atributo tem que ser calculado, então usar uma expressão aninhada delimitada por { } <book isbn = "{$x}"> { $b/title } </book> Se o nome e conteúdo tiverem quer calculados, então usar um constructor calculado element { name-expr } { content-expr } attribute { name-expr } { content-expr } If-Then-Else for $b in doc("books.xml")//book return <book> { $b/title } { for $a at $i in $b/author where $i <= 2 return <author>{string($a/last), ", ", string($a/first)}</author> } { if (count($b/author) > 2) then <author>et al.</author> else () } </book> Quantificadores existenciais FOR $b IN //book WHERE SOME $p IN $b//para SATISFIES contains($p, "sailing") AND contains($p, "windsurfing") RETURN $b/title Quantificadores universais FOR $b IN //book WHERE EVERY $p IN $b//para SATISFIES contains($p, "sailing") RETURN $b/title Tópicos próximas aulas XSLT Referências Peter Wood, Slides on “Representing and Querying Data on the Web”, http://www.dcs.bbk.ac.uk/~ptw/teaching/data-on-theweb.html. Dan Suciu, Slides on “The semistructured data model”, CSE 590ds: Management of XML and Semistructured Data, http://www.cs.washington.edu/education/courses/cse590 ds/01sp/ www.w3.org/XML/Query W3C's working group on XML query languages www.perfectxml.com/XQuery.html XQuery: A Guided Tour (book chapter from XQuery from the Experts)