XQuery (2ª parte)
Helena Galhardas
DEI IST
(baseado nos slides de Ioana Manolescu, acessíveis em:
http://www-rocq.inria.fr/~abitebou/Master-SSD/slxquery.pdf
)
Agenda
Formulação de interrogações
Expressões FLOWR
Sumário das expressões FLWOR
Claúsula order by
Permite uma ou mais especificações de ordem, em
que cada uma especifica uma expressão usada
para ordenar os tuplos
Exemplo:
for $a in doc(“books.xml”)//author
order by $a/last descending, $a/first
descending
return $a
Collations
Especifica o modo como as cadeias de caracteres
são comparadas e, consequentemente, ordenadas
Exemplo: A seguinte interrogação ordena os títulos
usando uma collation do Inglês dos EUA
for $t in doc(“books.xml”)//title
order by $t collation
http://www.example.com/collations/eng-us
return $t
Nota: A maior parte das interrogações usam a mesma
collation para todas as especificações de ordenação
Junções
As expressões FLOWR tornam mais fácil expressar junções sobre
documentos à la SQL.
Exemplo:
for $p in document("taxpayers.xml")//person
for $n in document("neighbors.xml")//neighbor
where $n/ssn = $p/ssn
return
<person>
<ssn> { $p/ssn } </ssn>
{ $n/ name }
<income> { $p/ income } </income>
</person>
Nota: A condição de junção pode ser expressa como um predicado XPath
no segundo for ou na claúsula where.
(Left) outer-join
Exemplo: Obter o título de cada livro, independentemente se ele
tem uma revisão associada. Se o livro tem uma revisão
associada, então as notas encontradas na revisão são
retornadas
for $t in doc(“books.xml”)//title
return
<review>
{ $t }
{
for $e in doc(“reviews.xml”)//entry
where $e/title = $t
return $e/remarks
}
</review>
Junção e agrupamento
Exemplo: Obter a lista dos departamentos com mais do que 10
empregados, ordenados pela média dos salários.
for $d in document("depts.xml")//deptno
let $e:=document("emps.xml")//employee[deptno =$d]
where count($e) >= 10
order by avg($e/salary) descending
return <big-dept>
{ $d ,
<headcount>{ count($e) } </headcount>,
<avgsal>{ avg($e/salary) } </avgsal>
}
</big-dept>
Nota: A construção {e1,e2, ··· ,en} é equivalente a:
{concat(e1,e2, ··· ,en)}.
Operações sobre listas
XQuery suporta operadores para manipular listas:
1.
Concatenação
2.
Operações de conjunto: união, intersecção, diferença
3.
Funções: remove(), index-of (), count(), avg(), min(), max(), etc.
Os valores distintos de uma lista podem ser coleccionados noutra lista (perde-se
identidade e ordem)
Exemplo:
Para cada editor, retorne o seu nome e o seu preço médio de livros.
for $p in
distinct-values(document("bib.xml")//publisher)
let $a :=
avg (document("bib.xml")//book[publisher=$p]/price )
return
<publisher>
<name>{ $p/text() }</name>
<avgprice>{ $a }</avgprice>
</publisher>
União, intersecção e diferença
Combinam sequências de nós: cada um destes operadores combina duas
sequências, e retorna uma sequência resultado pela ordem do documento.
Exemplo:
let $l := distinctvalues(doc(“books.xml”)//(author|editor)/last)
order by $l
return <last> { $l } </last>
O operador except aceita duas sequências de nós como operandos e
retorna uma sequência contendo todos os nós que ocorrem no primeiro
operando, mas não no segundo.
Exemplo: a interrogação seguinte retorna um livro com todos os seus filhos
excepto o preço
for $b in doc(“books.xml”)//book
where $b/title = “TCP/IP Illustrated”
return
<book>
{ $b/@* }
{ $b/* except $b/price }
</book>
Expressões if-then-else
Exemplo: Qual o “holding” dos documentos
publicados?
for $h in document("library.xml")//holding
return
<holding>
{ $h/title ,
if ($h/@type = "Journal")
then $h/editor
else $h/author }
</holding>
Expressões quantificadas: some
some exprime o quantificador existencial
Exemplo: Qual o documento que menciona
actividades de “sailing” e “windsurfing”
for $b in document("bib.xml")//book
where some $p in $b//paragraph
satisfies (contains($p,"sailing")
and contains($p ,"windsurfing"))
return $b/title
Expressões quantificadas: every
every exprime o quantificador universal
Exemplo: Qual o documento onde cada parágrafo
fala acerca de “sailing”
for $b in document("bib.xml")//book
where every $p in $b//paragraph
satisfies contains($p ,"sailing")
return $b/title
Funções pré-definidas
O XQuery tem um conjunto de funções e operadores prédefinidos, entre as quais:
min(), max(), count(), sum(), avg()
round(), floor(), ceiling(), concat(), etc
distinct-values(), doc(), collection(), not(), etc
Exemplo:
Quais os livros onde nenhum autor tem como último nome
Stevens
for $b in doc(“books.xml”)//book
where not (some $a in $b/author satisfies $a/last
= “Stevens”)
return $b
Funções definidas pelo utilizador
Se não conseguirmos encontrar a função XPath de que
necessitamos, então podemos escrever a nossa própria
Funções definidas pelo utilizador podem ser escritas em XQuery
usando a seguinte sintaxe:
declare function prefix:function_name($parameter
as datatype) as returnDatatype
{ (: ...insert FLOWR/XPath expression here... };
Notas:
O nome da função tem que ser precedido por um espaço de
nomes
O tipo de dados para os parâmetros e o valor de retorno é
opcional
É útil para estruturar interrogações complexas e para reutilizar
código
Quando o XQuery não se comporta
como esperado...
Se a interrogação não compila => reformulá-la
Podemos começar pelos use cases de XQuery
A interrogação é compilada, mas não funciona
A interrogação funciona, mas não dá os resultados
esperados => tentar compreender o que o parser
percebeu.
Implementações do XQuery
Entre aquelas que são de distribuição livre, temos:
Galax : completa, mas não muito eficiente
Saxon : em memória; implementado por Michael Kay, um
guru de XSL
MonetDB : baseado num motor orientado à coluna, em
memória; está entre os mais eficientes
eXist : uma interface muito amigável
QizX : Xavier Franc. Engraçado mas nada de especial
BerkeleyDB XML : pertence à Oracle, agora
SQL/XML: a ponte entre os dois
mundos (1)
As versões recentes do SQL (2003) incluem:
Um tipo atómico XML nativo, que pode ser interrogado no estilo
XQuery
Um conjunto de funções de publicação XML: que permitem extrair
elementos de XML a partir de dados relacionais usando interrogações
Regras de mapeamento: permitem exportar tabelas relacionais em
XML
Vantagens:
Manipulação uniforme de dados relacionais e XML
Motor de interrogações relacionais bem explorado
Facilidade de transformação de um formato no outro
Desvantagens:
Complexidade
SQL/XML: a ponte entre os dois
mundos (2)
Funções de publicação XML:
select xmlelement (name Customer ,
xmlattributes(c. city as city),
xmlforest (c.CustID,
c. Name as CustName ))
from customer c
Interrogações mistas:
select customer , XMLExtract (order,'/order/@date')
from orders
where XMLExists(order,'/order[//desc/text()="Shoes"]')
=1
A sintaxe SQL/XML precisa depende, muitas vezes, do vendedor.
Referências
Ioana Manolescu, slides about XQuery, course about
“Web Data Management and Distribution”, Master
Recherche Informatique Paris Sud, http://www-
rocq.inria.fr/~abitebou/Master-SSD/slxquery.pdf
www.perfectxml.com/XQuery.html
XQuery: A Guided Tour (book chapter from XQuery from
the Experts)