XQuery - Guia Rápido
O que é XQuery
XQuery é uma linguagem funcional usada para recuperar informações armazenadas em formato XML. XQuery pode ser usado em documentos XML, bancos de dados relacionais contendo dados em formatos XML ou bancos de dados XML. XQuery 3.0 é uma recomendação do W3C de 8 de abril de 2014.
A definição de XQuery conforme dada por sua documentação oficial é a seguinte -
XQuery é uma linguagem padronizada para combinar documentos, bancos de dados, páginas da Web e quase tudo mais. É amplamente implementado. É poderoso e fácil de aprender. XQuery está substituindo linguagens de middleware proprietárias e linguagens de desenvolvimento de aplicativos da web. XQuery está substituindo programas Java ou C ++ complexos por algumas linhas de código. XQuery é mais simples de trabalhar e mais fácil de manter do que muitas outras alternativas.
Características
Functional Language - XQuery é uma linguagem para recuperar / consultar dados baseados em XML.
Analogous to SQL - XQuery é para XML o que SQL está para bancos de dados.
XPath based - XQuery usa expressões XPath para navegar por documentos XML.
Universally accepted - XQuery é suportado por todos os principais bancos de dados.
W3C Standard - XQuery é um padrão W3C.
Benefícios do XQuery
Usando XQuery, os dados hierárquicos e tabulares podem ser recuperados.
XQuery pode ser usado para consultar estruturas de árvore e gráficas.
XQuery pode ser usado diretamente para consultar páginas da web.
XQuery pode ser usado diretamente para construir páginas da web.
XQuery pode ser usado para transformar documentos xml.
XQuery é ideal para bancos de dados baseados em XML e bancos de dados baseados em objetos. Os bancos de dados de objetos são muito mais flexíveis e poderosos do que os bancos de dados puramente tabulares.
Este capítulo elabora como configurar a biblioteca XQuery em um ambiente de desenvolvimento local.
Estamos usando um processador XQuery autônomo de código aberto Saxon Home Edition (Saxon-HE), que é amplamente utilizado. Este processador suporta XSLT 2.0, XQuery 3.0 e XPath 3.0 e é altamente otimizado para desempenho. O processador Saxon XQuery pode ser usado sem nenhum banco de dados XML. Usaremos um documento XML simples como nosso banco de dados em nossos exemplos.
Para usar o processador Saxon XQuery, você deve ter saxon9he.jar, saxon9-test.jar, saxon9-unpack, saxon9-xqj.jar no classpath de seu aplicativo. Esses arquivos jar estão disponíveis no arquivo de downloadSaxonHE9-6-0-1J.zipBaixe SaxonHE9-6-0-1J.zip .
Exemplo
Usaremos o processador Saxon XQuery baseado em Java para testar books.xqy, um arquivo que contém a expressão XQuery em nosso documento XML de amostra, ou seja, books.xml.
Neste exemplo, veremos como escrever e processar uma consulta para obter os elementos do título dos livros cujo preço é maior que 30.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>40.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
books.xqy
for $x in doc("books.xml")/books/book where $x/price>30
return $x/title
XQueryTester.java
package com.tutorialspoint.xquery;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;
import com.saxonica.xqj.SaxonXQDataSource;
public class XQueryTester {
public static void main(String[] args){
try {
execute();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (XQException e) {
e.printStackTrace();
}
}
private static void execute() throws FileNotFoundException, XQException{
InputStream inputStream = new FileInputStream(new File("books.xqy"));
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
XQPreparedExpression exp = conn.prepareExpression(inputStream);
XQResultSequence result = exp.executeQuery();
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
}
Etapas para executar XQuery em XML
Step 1 - Copie XQueryTester.java para qualquer local, digamos, E: > java
Step 2 - Copie books.xml para o mesmo local, E: > java
Step 3 - Copie books.xqy para o mesmo local, E: > java
Step 4- Compilar XQueryTester.java usando o console. Certifique-se de ter o JDK 1.5 ou posterior instalado em sua máquina e os classpaths configurados. Para obter detalhes sobre como usar JAVA, consulte nosso Tutorial JAVA
E:\java\javac XQueryTester.java
Step 5 - Execute XQueryTester
E:\java\java XQueryTester
Resultado
Você obterá o seguinte resultado -
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
Exemplo de compreensão
books.xml representa os dados de amostra.
books.xqy representa a expressão XQuery que deve ser executada em books.xml. Vamos entender a expressão em detalhes no próximo capítulo.
XQueryTester, um programa executor de XQuery baseado em Java, lê books.xqy, passa-o para o processador de expressão XQuery e executa a expressão. Em seguida, o resultado é impresso.
Exemplo
A seguir está um documento XML de amostra contendo os registros de uma livraria de vários livros.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>70.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
A seguir está um documento Xquery de amostra contendo a expressão de consulta a ser executada no documento XML acima. O objetivo é obter os elementos de título desses nós XML em que o preço é maior que 30.
books.xqy
for $x in doc("books.xml")/books/book
where $x/price>30 return $x/title
Resultado
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
Verificar Resultado
Para verificar o resultado, substitua o conteúdo de books.xqy (fornecido no capítulo Configuração do ambiente ) pela expressão XQuery acima e execute o programa java XQueryTester.
Expressões XQuery
Vamos entender cada parte da expressão XQuery acima.
Uso de funções
doc("books.xml")
doc () é uma das funções XQuery usadas para localizar a origem XML. Aqui passamos "books.xml". Considerando o caminho relativo, books.xml deve estar no mesmo caminho onde books.xqy está presente.
Uso de expressões XPath
doc("books.xml")/books/book
XQuery usa expressões XPath intensamente para localizar a parte necessária do XML na qual a pesquisa deve ser feita. Aqui, escolhemos todos os nós de livros disponíveis no nó de livros.
Iterar os objetos
for $x in doc("books.xml")/books/book
XQuery trata os dados xml como objetos. No exemplo acima, $ x representa o nó selecionado, enquanto o loop for itera sobre a coleção de nós.
Aplicar a condição
where $x/price>30
Como $ x representa o nó selecionado, "/" é usado para obter o valor do elemento necessário; A cláusula "where" é usada para colocar uma condição nos resultados da pesquisa.
Devolve o resultado
return $x/title
Como $ x representa o nó selecionado, "/" é usado para obter o valor do elemento necessário, preço, título; A cláusula "return" é usada para retornar os elementos dos resultados da pesquisa.
FLWOR é uma sigla que significa "For, Let, Where, Order by, Return". A lista a seguir mostra o que eles representam em uma expressão FLWOR -
F - Para - seleciona uma coleção de todos os nós.
L - Let - Coloca o resultado em uma variável XQuery.
W - Onde - seleciona os nós especificados pela condição.
O - Ordenar por - ordena os nós especificados de acordo com os critérios.
R - Retornar - Retorna o resultado final.
Exemplo
A seguir está um documento XML de amostra que contém informações sobre uma coleção de livros. Usaremos uma expressão FLWOR para recuperar os títulos desses livros com preço superior a 30.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>70.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
O seguinte documento Xquery contém a expressão de consulta a ser executada no documento XML acima.
books.xqy
let $books := (doc("books.xml")/books/book) return <results> { for $x in $books where $x/price>30
order by $x/price return $x/title
}
</results>
Resultado
<title lang="en">Learn XQuery in 24 hours</title>
<title lang="en">Learn .Net in 24 hours</title>
Verificar Resultado
Para verificar o resultado, substitua o conteúdo de books.xqy (fornecido no capítulo Configuração do ambiente ) pela expressão XQuery acima e execute o programa java XQueryTester.
XQuery também pode ser facilmente usado para transformar um documento XML em uma página HTML. Dê uma olhada no exemplo a seguir para entender como o XQuery faz isso.
Exemplo
Usaremos o mesmo arquivo books.xml. O exemplo a seguir usa dados de extração XQuery de books.xml e cria uma tabela HTML contendo os títulos de todos os livros junto com seus respectivos preços.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>70.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
A seguir está a expressão Xquery que deve ser executada no documento XML acima.
books.xqy
let $books := (doc("books.xml")/books/book) return <table><tr><th>Title</th><th>Price</th></tr> { for $x in $books order by $x/price
return <tr><td>{data($x/title)}</td><td>{data($x/price)}</td></tr>
}
</table>
</results>
Resultado
<table>
<tr>
<th>Title</th>
<th>Price</th>
</tr>
<tr>
<td>Learn XPath in 24 hours</td>
<td>16.50</td>
</tr>
<tr>
<td>Learn Java in 24 Hours</td>
<td>30.00</td>
</tr>
<tr>
<td>Learn XQuery in 24 hours</td>
<td>50.00</td>
</tr>
<tr>
<td>Learn .Net in 24 hours</td>
<td>70.50</td>
</tr>
</table>
Verificar Resultado
Para verificar o resultado, substitua o conteúdo de books.xqy (fornecido no capítulo Configuração do ambiente ) pela expressão XQuery acima e execute o programa java XQueryTester.
Expressões XQuery
Aqui, usamos as seguintes expressões XQuery -
função data () para avaliar o valor do elemento de título, e
{} operador para informar ao processador XQuery para considerar data () como uma função. Se o operador {} não for usado, os dados () serão tratados como texto normal.
XQuery é compatível com XPath. Ele usa expressões XPath para restringir os resultados da pesquisa em coleções XML. Para obter mais detalhes sobre como usar XPath, consulte nosso Tutorial XPath .
Lembre-se da seguinte expressão XPath que usamos anteriormente para obter a lista de livros.
doc("books.xml")/books/book
Exemplos XPath
Usaremos o arquivo books.xml e aplicaremos XQuery a ele.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>40.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
Fornecemos aqui três versões de uma instrução XQuery que cumprem o mesmo objetivo de exibir os títulos dos livros com um valor de preço superior a 30.
XQuery - Versão 1
(: read the entire xml document :)
let $books := doc("books.xml") for $x in $books/books/book where $x/price > 30
return $x/title
Resultado
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
XQuery - Versão 2
(: read all books :)
let $books := doc("books.xml")/books/book
for $x in $books
where $x/price > 30 return $x/title
Resultado
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
XQuery - Versão 3
(: read books with price > 30 :)
let $books := doc("books.xml")/books/book[price > 30] for $x in $books return $x/title
Resultado
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
Verifique o resultado
Para verificar o resultado, substitua o conteúdo de books.xqy (fornecido no capítulo Configuração do ambiente ) pela expressão XQuery acima e execute o programa java XQueryTester.
As sequências representam uma coleção ordenada de itens onde os itens podem ser de tipos semelhantes ou diferentes.
Criando uma sequência
As sequências são criadas usando parênteses com strings entre aspas ou aspas duplas e números como tal. Os elementos XML também podem ser usados como itens de uma sequência.
Expressão XQuery
let $items := ('orange', <apple/>, <fruit type="juicy"/>, <vehicle type="car">sentro</vehicle>, 1,2,3,'a','b',"abc") let $count := count($items) return <result> <count>{$count}</count>
<items>
{
for $item in $items
return <item>{$item}</item>
}
</items>
</result>
Resultado
<result>
<count>10</count>
<items>
<item>orange</item>
<item>
<apple/>
</item>
<item>
<fruit type="juicy"/>
</item>
<item>
<vehicle type="car">Sentro</vehicle>
</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>a</item>
<item>b</item>
<item>abc</item>
</items>
</result>
Vendo os itens de uma sequência
Os itens de uma sequência podem ser iterados um a um, usando índice ou valor. O exemplo acima iterou os itens de uma sequência, um por um. Vamos ver as outras duas formas de ação.
Expressão XQuery (Índice)
let $items := (1,2,3,4,5,6)
let $count := count($items)
return
<result>
<count>{$count}</count> <items> { for $item in $items[2] return <item>{$item}</item>
}
</items>
</result>
Resultado
<result>
<count>6</count>
<items>
<item>2</item>
</items>
</result>
Expressão XQuery (valor)
let $items := (1,2,3,4,5,6) let $count := count($items) return <result> <count>{$count}</count>
<items>
{
for $item in $items[. = (1,2,3)]
return <item>{$item}</item>
}
</items>
</result>
Resultado
<result>
<count>6</count>
<items>
<item>1</item>
<item>2</item>
<item>3</item>
</items>
</result>
A tabela a seguir lista as funções de sequência comumente usadas fornecidas pelo XQuery.
Sr. Não | Nome e Descrição |
---|---|
1 | Conta os itens em uma sequência. |
2 | Retorna a soma dos itens em uma sequência. |
3 | Retorna a média dos itens em uma sequência. |
4 | Retorna o item de valor mínimo em uma sequência. |
5 | Retorna o item com valor máximo em uma sequência. |
6 | valores distintos ($ seq as item () *) Retorna seleciona itens distintos de uma sequência. |
7 | subsequência ($ seq as item () *, $startingLoc as xs:double, $comprimento como xs: double) Retorna um subconjunto da sequência fornecida. |
8 | inserir antes ($seq as item()*, $posição como xs: inteiro, $ insere como item () *) Insere um item em uma sequência. |
9 | remove ($ seq as item () *, $ position as xs: integer) Remove um item de uma sequência. |
10 | reverso ($ seq como item () *) Retorna a sequência reversa. |
11 | índice de($seq as anyAtomicType()*, $target como anyAtomicType ()) Retorna índices como inteiros para indicar a disponibilidade de um item em uma sequência. |
12 | Retorna o último elemento de uma sequência quando usado na expressão de predicado. |
13 | Usado em expressões FLOWR para obter a posição de um item em uma sequência. |
A tabela a seguir lista as funções de manipulação de string comumente usadas fornecidas pelo XQuery.
Sr. Não | Nome e Descrição |
---|---|
1 | string-length ($ string as xs: string) as xs: integer Retorna o comprimento da string. |
2 | concat ($ input as xs: anyAtomicType?) as xs: string Retorna a string concatenada como saída. |
3 | string-join ($sequence as xs:string*, $delimitador como xs: string) como xs: string Retorna a combinação de itens em uma sequência separada por um delimitador. |
A tabela a seguir lista as funções de data comumente usadas fornecidas por XQuery.
Sr. Não | Nome e Descrição |
---|---|
1 | Retorna a data atual. |
2 | Retorna a hora atual. |
3 | Retorna a data e a hora atuais. |
A seguir está a lista de funções de expressão regular comumente usadas fornecidas por XQuery
Sr. Não | Nome e Descrição |
---|---|
1 | Retorna verdadeiro se a entrada corresponder à expressão regular fornecida. |
2 | substituir($input, $regex, $ string) Substitui a string de entrada correspondente pela string fornecida. |
3 | Retorna uma sequência de itens que correspondem à expressão regular. |
XQuery fornece uma construção if-then-else muito útil para verificar a validade dos valores de entrada transmitidos. A seguir, está a sintaxe da construção if-then-else.
Sintaxe
if (condition) then
...
else
...
Exemplo
Usaremos o arquivo books.xml a seguir e aplicaremos a ele a expressão XQuery contendo uma construção if-then-else para recuperar os títulos desses livros com um valor de preço maior que 30.
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book category="JAVA">
<title lang="en">Learn Java in 24 Hours</title>
<author>Robert</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="DOTNET">
<title lang="en">Learn .Net in 24 hours</title>
<author>Peter</author>
<year>2011</year>
<price>40.50</price>
</book>
<book category="XML">
<title lang="en">Learn XQuery in 24 hours</title>
<author>Robert</author>
<author>Peter</author>
<year>2013</year>
<price>50.00</price>
</book>
<book category="XML">
<title lang="en">Learn XPath in 24 hours</title>
<author>Jay Ban</author>
<year>2010</year>
<price>16.50</price>
</book>
</books>
A seguinte expressão XQuery deve ser aplicada ao documento XML acima.
books.xqy
<result>
{
if(not(doc("books.xml"))) then (
<error>
<message>books.xml does not exist</message>
</error>
)
else (
for $x in doc("books.xml")/books/book
where $x/price>30 return $x/title
)
}
</result>
Resultado
<result>
<title lang="en">Learn .Net in 24 hours</title>
<title lang="en">Learn XQuery in 24 hours</title>
</result>
Verifique o resultado
Para verificar o resultado, substitua o conteúdo de books.xqy (fornecido no capítulo Configuração do ambiente ) pela expressão XQuery acima e execute o programa java XQueryTester.
XQuery fornece a capacidade de escrever funções personalizadas. Listadas abaixo estão as diretrizes para criar uma função personalizada.
Use a palavra-chave declare function para definir uma função.
Use os tipos de dados definidos no esquema XML atual
Coloque o corpo da função entre chaves.
Prefixe o nome da função com um namespace XML.
A sintaxe a seguir é usada ao criar uma função personalizada.
Sintaxe
declare function prefix:function_name($parameter as datatype?...)
as returnDatatype?
{
function body...
};
Exemplo
O exemplo a seguir mostra como criar uma função definida pelo usuário em XQuery.
Expressão XQuery
declare function local:discount($price as xs:decimal?,$percentDiscount as xs:decimal?) as xs:decimal? { let $discount := $price - ($price * $percentDiscount div 100) return $discount
};
let $originalPrice := 100 let $discountAvailed := 10
return ( local:discount($originalPrice, $discountAvailed))
Resultado
90
Verifique o resultado
Para verificar o resultado, substitua o conteúdo de books.xqy (fornecido no capítulo Configuração do ambiente ) pela expressão XQuery acima e execute o programa java XQueryTester.