XPath

XPath é oque há para se trabalhar com XML. Já falamos um pouco sobre este assunto de forma superficial, porem não o suficiente, por ser um recurso de peso merece respeito e é claro uma postagem exclusiva.

Afinal de contas oque é XPath, sabemos que é uma abreviação para XML Path Language e que se trata de uma linguagem de consulta própria para XML, nos possibilitando construir consultas com complexidades sem precedentes, de forma simples e direta podemos usar de operadores, predicados,  funções booleanas, funções numéricas e muito mais para se montar uma consulta. Suportado por muitas linguagens de programação, ferramentas para processamento de XML,  seletores CSS e até mesmo incorporado em consultas para banco de dados, o XPath tem se mostrado um recurso indispensável e bastante útil para se trabalhar com XML. A sua atual versão é a 2.0, porem a versão 1.0 ainda é fortemente utilizada, e já começam a surgir novas especificações para sua versão 3.0, porem nada em fase final.

Na ultima postagem sobre XML, montamos alguns documentos e pretendo utilizar alguns deles como exemplo nesta postagem, para evitar mais trabalho, vejamos um deles abaixo:

<?xml version="1.0" encoding="utf-8"?>
<Pedidos>
  <!--Este Elemento representara a estrutura de um 'Pedido' realizado pelo cliente  -->
  <Pedido IdPedido="1">
    <ItensDoPedido>
      <Item IdItem="557">
        <Nome>Geladeira XAVECO</Nome>
        <Preco>1000</Preco>
      </Item>
      <Item IdItem="558">
        <Nome>Cadeiro XAMEGO</Nome>
        <Preco>80.5</Preco>
      </Item>
    </ItensDoPedido>
  </Pedido>
  <!--Este Elemento representara a estrutura de um 'Pedido' realizado pelo cliente  -->
  <Pedido IdPedido="2">
    <ItensDoPedido>
      <Item IdItem="559">
        <Nome>Celular CADEMEUCHIPPEDROOO</Nome>
        <Preco>500</Preco>
      </Item>
    </ItensDoPedido>
  </Pedido>
</Pedidos>

O XPath trabalha fortemente sobre a arvore do documento XML, possibilitando navegar sobre esta arvore. Vejamos a representação do XML acima.

xmltree

Interessante né, procure sempre ter esta visão de um XML, facilita muito para montar suas consultas.

O XPath trabalha sobre três componentes principais, Axis (eixos), Node test (nó de teste) e Predicates (predicados) sendo que neste ultimo componente podem existir zero ou muitos dependendo da consulta. Uma expressão XPath é avaliada sobre os nós do contexto, um eixo como ‘filho’ ou ‘descendente’ deste nó principal especifica a direção para onde devemos navegar a partir do nó deste contexto. Usamos do nó de teste e predicados ​​para filtrar os nós especificados por uma consulta sobre o eixo principal. Vamos tomar como exemplo o nó de teste “Pedidos”, sabemos que todos os nós filhos possuem este nó como pai e será nesse eixo principal que a consulta irá atuar. Ainda podemos usar predicados apenas para especificar que os nós selecionados tem que ter certas propriedades que se encaixem nas definições da consulta.

O XPath oferece uma sintaxe abreviada e a sintaxe não abreviada para realizarmos consultas, sendo que a primeira sintaxe é bastante utilizada, porem não tão completa quanto a segunda sintaxe. Vou usar de um programa chamado XML Quire, eu acho um dos melhores para se trabalhar com XML, é leve, pratico e simples de usar, basta copiar/colar o XML e clicar sobre o ícone em formato de “lupa” e montar sua consulta, porem existem diversos sites que suportam XPath, um deles é muito simples de usar, se chama PathEnq, fica ao seu critério agora.

Vamos supor que eu quero selecionar todos os elementos “Preco” do meu documento XML, com a sintaxe abreviada ficaria desta maneira:

/Pedidos/Pedido/ItensDoPedido/Item/Preco

Enquanto que, com a sintaxe não abreviada a consulta ficaria desta maneira:

/child::Pedidos/child::Pedido/child::ItensDoPedido/child::Item/child::Preco

Comparando as sintaxes podemos notar que a sintaxe não abreviada possui um suporte muito maior para se trabalhar com eixos.

Axis

Sua função é nos dizer qual direção de navegação vamos tomar dentro de um documento XML. Os eixos disponíveis são estes:

Não abreviada Abreviada Descrição Observações
ancestor N/D Todos os nós ancestrais, exceto o nó atual
ancestor-or-self N/D Todos os nós ancestrais, incluindo o nó atual
attribute @ Pega o atribuo do nó atual @IdItem é um atalho para attribute::IdItem
child N/D Seleciona todos os nós filho do nó atual Pedidos é um atalho para child::Pedidos
descendant N/D Todos os nós descendentes, exceto o nó atual
descendant-or-self // Todos os nós descendentes, incluindo o nó atual // é um atalho para descendant-or-self::Pedido/
following N/D Todos os nós descendentes, que possuem fechamento de tag após o nó atual
following-sibling N/D Todos os nós irmãos, que possuem fechamento de tag após ou antes do nó atual
namespace N/D
parent .. Todos os nós que são parentes do nó atual .. é um atalho para parent::node()
preceding N/D Seleciona todos os nós precendentes do nó atual que possua abertu/fechamento de tag
preceding-sibling N/D Seleciona todos os nós precendentes do nó atual que não possua abertu/fechamento de tag
self . Seleciona o nó atual . é um atalho para self::node()

Node tests

Geralmente usado sobre os resultado das consultas, afim de obter informações mais especificas do nó atual, tais como comentários, texto, nós e etc. Os nós de teste disponíveis são estes:

Node tests Descrição Exemplo
comment() Todos os comentarios contido abaixo do nó atual //Pedidos/comment()
text() Todos os textos contido no nó atual //Nome/text()
node() Todos os nós contido no nó atual //Pedidos/node()

Predicates

Predicados são escritos como expressões, porem usando de colchetes, ele pode ser usado para restringir um conjunto de nós para selecionar apenas os nós que atendam uma condição, se esta condição for verdadeira o nó é selecionado. Não existe um limite de predicados que possam ser utilizados em uma consulta e também não existe uma ordem a ser utilizada, podemos trabalhar com funções, operadores matemáticas ou quaisquer condições desde que resulte em um valor booleano, porem se informamos apenas um numero inteiro dentro deste predicado, sera retornando o elemento corresponde ao seu índice nesta consulta. Não existe segredo quanto aos exemplos, basta utilizar de colchetes e montar suas condições, vejamos alguns:

Descrição Exemplo
Apenas o primeiro nó da consulta sobre todos os pedidos //Pedido[1]
Apenas o ultimo nó da consulta sobre todos os pedidos //Pedido[last()]
Todos os pedidos onde o atributo IdPedido é igual a 2 //Pedido[@IdPedido=”2″]

Funções, operadores e expressões relacionais

A XPath oferece de diversas funções para se trabalhar junto de uma consulta, sejam elas funções numéricas, string, conjuntos de nós e até mesmo funções booleanas, sendo que muitas destas funções podem ser combinada juntas de predicados, vejamos algumas disponíveis e seus respectivos tipo:

Funções Descrição Tipo Exemplo
number Converte o resultado em numero Numérico number(//Item[@IdItem=558]/Preco)
ceiling() Retornar o menor inteiro que não seja menor que o argumento Numérico ceiling(//Item[@IdItem=558]/Preco)
floor() Retornar o maior inteiro que não seja maior que o argumento Numérico floor(//Item[@IdItem=558]/Preco)
sum() Soma os valores dos nós numéricos de acordo com a consulta Numérico sum(//Pedido[@IdPedido=”1″]/ItensDoPedido/Item/Preco)
round() Arredonda o numero para o próximo numero inteiro com base no valor atual Numérico round(//Item[@IdItem=558]/Preco)
concat() Concatena valores dos nos, sendo que seus argumentos são infinitos String concat((//Nome)[last()], ‘ < é o ultimo nome !’)
contains() Retorna “true” se o segundo argumento conter no primeiro argumento String contains(((//Nome)[last()])[text language=”()”][/text], ‘Celular’)
starts-with() Retorna “true” se o segundo argumento começa no primeiro argumento String starts-with(((//Nome)[last()])[text language=”()”][/text], ‘Celular’)
string-length() Retorna a quantidade caracteres contido no elemento String string-length(((//Nome)[last()])[text language=”()”][/text])
substring() Retorna uma quantidade do texto de acordo com os argumentos informados String substring(((//Nome)[last()])[text language=”()”][/text], 1, 8)
count() Retorna quantidade de nós encontrados na consulta Conjuntos de nós count(//Nome)
last() Retorna último nó da lista de nós encontrados Conjuntos de nós (//Nome)[last()]
name() Retorna o nome do nó Conjuntos de nós name((//Nome)[last()])
position() Retorna a posição do elemento Conjuntos de nós ((//Nome)[last()])[position()]
true() Retorna valor verdadeiro Booleano true()
boolean() Converte o valor em booleano Booleano boolean(1)
not() Inverte o valor booleano, negando de fato o valor retornado Booleano not(boolean(1))
false() Retorna valor falso Booleano false()

Operadores e expressões relacionais não fogem muito do que foi mostrado sobre as funções, sendo que o XPath disponibiliza uma serie de operadores, tais como operadores de comparação, operadores lógicos, operadores aritméticos e até mesmo operadores de união, podendo resultar da união de consultas no XML.

Expressões Descrição Tipo Exemplo
= Igual Igualdade ((//Preco)[last()])[text language=”()”][/text] = 500
!= Diferente Igualdade ((//Preco)[last()])[text language=”()”][/text] != 500
+ Adição Numericas ((//Preco)[last()])[text language=”()”][/text] + 500
Subtração Numericas ((//Preco)[last()])[text language=”()”][/text] – 500
* Multiplicação Numericas ((//Preco)[last()])[text language=”()”][/text] * 2
div Divisão Numericas ((//Preco)[last()])[text language=”()”][/text] div 2
mod Módulo, resto de uma divisão Numericas ((//Preco)[last()])[text language=”()”][/text] mod 2
or Ou Boleanas ((//Preco)[last()])[text language=”()”][/text]  = 500 or ((//Preco)[last()])[text language=”()”][/text] > 100
and E Boleanas ((//Preco)[last()])[text language=”()”][/text] = 500 and (((//Preco)[last()])[text language=”()”][/text] mod 2) = 0
< Menor Relacionais ((//Preco)[last()])[text language=”()”][/text] < 500
<= Menor ou igual Relacionais ((//Preco)[last()])[text language=”()”][/text] <= 500
> Maior Relacionais ((//Preco)[last()])[text language=”()”][/text] > 500
>= Maior ou igual Relacionais ((//Preco)[last()])[text language=”()”][/text] >= 500
| Une duas consultas resultando em um único resultado União //Preco | //Pedidos

Como podemos ver acima, XPath é um assunto bem extenso e temos que aprender com cautela, falar sobre todos os seus recursos disponíveis em uma unica postagem é impossível, usei como embasamento a própria documentação oficial da W3C sobre XPath e como complemento alguns trechos do livro Beginning XML  (capitulo 7 ) e mesmo assim a postagem não abordou tudo sobre o assunto, porem falei sobre alguns pontos chave que devemos saber e creio que seja o suficiente para se montar uma consulta para XML de forma simples e direta. Bom, por hoje é só e espero que tenham gostado desta postagem sobre XPath, aguardem as próximas publicações sobre as classes suportadas no .NET Framework para se trabalhar com XML.