XML - Tutorial XPath


Colaboração: Otávio Augusto Bizetto Penatti
(Este tutorial é uma tradução do tutorial de XPath da W3Schools, disponível em https://www.w3schools.com/xml/

Tutorial XPath

XPath é um conjunto de regras de sintaxe para definir partes de um documento XML.

XPath é o elemento principal no padrão W3C XSLT. Sem o conhecimento de XPath você não será capaz de criar documentos XSLT.

Introdução ao XPath

XPath é um conjunto de regras de sintaxe para definir partes de um documento XML.

O que é XPath?

Como caminhos de arquivos tradicionais

XPath usa expressões de caminho para identificar nós em um documento XML. Essas expressões de caminho se parecem muito com as expressões que você vê quando você trabalha num sistema de arquivos de um computador:   w3schools/xpath/default.asp

Exemplo de XPath

Veja esse documento XML simples:  

 <?xml version="1.0" encoding="ISO-8859-1"?>
  <catalog>
    <cd country="USA">
      <title>Empire Burlesque</title>
      <artist>Bob Dylan</artist>
      <price>10.90</price>
    </cd>
    <cd country="UK">
      <title>Hide your heart</title>
      <artist>Bonnie Tyler</artist>
      <price>9.90</price>
    </cd>
    <cd country="USA">
      <title>Greatest Hits</title>
      <artist>Dolly Parton</artist>
      <price>9.90</price>
    </cd>
  </catalog>

A expressão XPath abaixo seleciona o elemento RAIZ catalog:   /catalog

A expressão XPath abaixo seleciona todos os elementos cd do elemento catalog:   /catalog/cd

A expressão XPath abaixo seleciona todos os elementos price de todos os elementos cd do elemento catalog:   /catalog/cd/price

Nota: Se o caminho começa com uma barra ( / ) ele representa um caminho absoluto para um elemento!

XPath define uma biblioteca de funções padrão

XPath define uma biblioteca de funções padrão para trabalhar com strings, números e expressões booleanas.

A expressão XPath abaixo seleciona todos os elementos cd que tem um elemento price que tem um valor maior que 10.80:

  /catalog/cd[price>10.80]

XPath é usado em XSLT

XPath é o elemento principal do padrão XSLT. Sem o conhecimento de XPath você não será capaz de criar documentos XSLT.

Você pode ler mais sobre XSLT no nosso tutorial XSLT em inglês ou em português.

XPath é um padrão W3C

XPath foi liberado com uma recomendação W3C em 16 de novembro de 1999 como uma linguagem para endereçar partes de um documento XML.

XPath foi desenvolvido para ser usado por XSLT, XPointer e outros softwares XML parsing.

Você pode ler mais sobre padrões XML e XSl em nosso tutorial W3C

Sintaxe XPath

XPath usa expressões de caminho para localizar nós dentro de documentos XML.

Documento XML de Exemplo

Nós usaremos esse documento XML simples para descrever a sintaxe XPath:

  <?xml version="1.0" encoding="ISO-8859-1"?>
  <catalog>
    <cd country="USA">
      <title>Empire Burlesque</title>
      <artist>Bob Dylan</artist>
      <price>10.90</price>
    </cd>
    <cd country="UK">
      <title>Hide your heart</title>
      <artist>Bonnie Tyler</artist>
      <price>9.90</price>
    </cd>
    <cd country="USA">
      <title>Greatest Hits</title>
      <artist>Dolly Parton</artist>
      <price>9.90</price>
    </cd>
  </catalog>

Localizando Nós

Documentos XML podem ser representados como árvores de nós (muito similar à visão em árvore das pastas do seu computador).

XPath usa uma expressão padrão para identificar nós em um documento XML. Um padrão XPath é uma lista nomes de elementos filhos separada por barras que descreve o caminho através do documento XML. O padrão "seleciona" elementos que combinam com o caminho.

A expressão XPath a seguir seleciona todos os elementos preço de todos os elementos cd do elemento catalog:   /catalog/cd/price

Nota: Se o caminho começa com uma barra ( / ) ele representa um caminho absoluto para um elemento!

Nota: Se o caminho começa com duas barras ( // ) então todos os elementos no documento que se encaixam no critério serão selecionados (mesmo que eles estejam em níveis diferentes da árvore XML)!

A expressão XPath a seguir seleciona todos os elementos cd no documento:   //cd

Selecionando elementos desconhecidos

Curingas ( * ) podem ser usados para selecionar elementos XML desconhecidos.

A expressão XPath a seguir seleciona todos os elementos filhos de todos os elementos cd do elemento catalog:   /catalog/cd/*

A expressão XPath a seguir seleciona todos os elementos price que são elementos netos do elemento catalog:   /catalog/*/price

A expressão XPath a seguir seleciona todos os elementos price que têm dois ancestrais:   /*/*/price

A expressão XPath a seguir seleciona todos os elementos no documento:   //*

Selecionando Seções

Usando-se colchetes numa expressão XPath você pode especificar um elemento adiante.

A expressão XPath a seguir seleciona o primeiro elemento cd filho do elemento catalog:   /catalog/cd[1]

A expressão XPath a seguir seleciona o último elemento cd filho do elemento catalog (Nota: não existe a função first()):   /catalog/cd[last()]

A expressão XPath a seguir seleciona todos os elementos cd do elemento catalog que tem um elemento price:   /catalog/cd[price]

A expressão XPath a seguir seleciona todos os elementos cd do elemento catalog que tem um elemento price com valor de 10.90:   /catalog/cd[price=10.90]

A expressão XPath a seguir seleciona todos os elementos price de todos os elementos cd do elemento catalog que tem um elemento price com valor de 10.90:   /catalog/cd[price=10.90]/price

Selecionando vários caminhos

Usando o operador "|" numa expressão XPath você pode selecionar vários caminhos.

A expressão XPath a seguir seleciona todos os elementos title e artist do elemento cd do elemento catalog:   /catalog/cd/title | /catalog/cd/artist

A expressão XPath a seguir seleciona todos os elementos title e artist do documento:   //title | //artist

A expressão XPath a seguir seleciona todos os elementos title, artist e price do documento:   //title | //artist | //price

A expressão XPath a seguir seleciona todos os elementos title do elemento cd do elemento catalog, e todos os elementos artist no documento:   /catalog/cd/title | //artist

Em XPath todos os atributos são especificados pelo prefixo "@".

Esta expressão XPath seleciona todos os atributos chamados country:   //@country

Esta expressão XPath seleciona todos os elementos cd que tem um atributo chamado country:   //cd[@country]

Esta expressão XPath seleciona todos os elementos cd que tem algum atributo:   //cd[@*]

Esta expressão XPath seleciona todos os elementos cd que tem um atributo chamado country com valor 'UK':   //cd[@country='UK']

XPath Location Paths (Caminho Locais XPath)

Uma expressão de caminho local (location path) resulta em um conjunto de nós.

Expressão de Caminho Local

Um caminho local pode ser absoluto ou relativo.

Um caminho local absoluto começa com uma barra ( / ) e um caminho local relativo não. Em ambos os casos o caminho local consiste de um ou mais níveis de localização, cada um separado por uma barra:

Um caminho local absoluto:    /step/step/...
 

Um caminho local relativo:  step/step

Os níveis de localização são avaliados em ordem um de cada vez, da esquerda pra direita. Cada nível é avaliado segundo os nós no conjunto de nós atual. Se o caminho local é absoluto, o conjunto de nós atual é o nó raiz. Se o caminho local é relativo, o conjunto de nós atual consiste do nó onde a expressão está sendo usada. Níveis de localização consistem de:

A sintaxe para um nível de localização é:   nomeeixo::noteste[predicado]

Exemplo:    child::price[price=9.90]

Eixos e Nós de Teste

Um eixo define um conjunto de nós relativo ao nó atual. Um nó de teste é usado para identificar um nó dentro de um eixo. Nós podemos executar um nó de teste por nome ou por tipo.

Nome do Eixo Descrição
ancestor Contém todos os ancestrais (pais, avós, etc) do nó atual. Nota: Este eixo incluirá sempre o nó raiz, a menos que o nó atual seja o nó raiz
ancestor-or-self Contém o nó atual mais todos os seus ancestrais (pai, avô, etc)
attribute Contém todos os atributos do nó atual
child Contém todos os filhos do nó atual
descendant Contém todos os descendentes (filhos, netos, etc) do nó atual. Nota: Este eixo nunca contém atributos ou nós namespace
descendant-or-self Contém o nó atual mais todos os seus descendentes (filhos, netos, etc)
following Contém tudo no documento depois da tag de fechamento do nó atual
following-sibling Contém todos os irmãos depois do nó atual. Nota: Se o nó atual é um nó atributo ou um nó namespace, este eixo estará vazio
namespace Contém todos os nós namespace do nó atual
parent Contém o pai do nó atual
preceding Contém tudo no documento que está antes da tag de abertura do nó atual
preceding-sibling Contém todos os irmãos antes do nó atual. Nota: Se o nó atual é um nó atributo ou um nó namespace, este eixo estará vazio
self Contém o nó atual

Exemplos

Exemplo Resultado
child::cd Seleciona todos os elementos cd que são filhos do nó atual (se o nó atual não tem cds filhos, será selecionado um conjunto vazio de nós)
attribute::src Seleciona o atributo src do nó atual (se o nó atual não tem atributo src, será selecionado um conjunto vazio de nós)
child::* Seleciona todos os elementos filhos do nó atual
attribute::* Seleciona todos os atributos do nó atual
child::text() Seleciona o nó texto filho do nó atual
child::node() Seleciona todos os filhos do nó atual
descendant::cd Seleciona todos os elementos cd descendentes do nó atual
ancestor::cd Seleciona todos os cds ancestrais do nó atual
ancestor-or-self::cd Seleciona todos os cds ancestrais do nó atual e, se o nó atual é um elemento cd, seleciona o nó atual também
child::*/child::price Seleciona todos os preços netos do nó atual
/ Seleciona a raiz do documento

Predicados

Um predicado filtra um conjunto de nós em um novo conjunto de nós. Um predicado fica dentro de colchetes ( [] ).

Exemplos

Exemplo Resultado
child::price[price=9.90] Seleciona todos os elementos price que são filhos do nó atual com um preço igual a 9.90
child::cd[position()=1] Seleciona o primeiro cd filho do nó atual
child::cd[position()=last()] Seleciona o último cd filho do nó atual
child::cd[position()=last()-1] Seleciona o penúltimo cd filho do nó atual
child::cd[position()<6] Seleciona os primeiros cinco cds filhos do nó atual
/descendant::cd[position()=7] Seleciona o sétimo elemento cd no documento
child::cd[attribute::type="classic"] Seleciona todos os cds filhos do nó atual que têm um atributo tipo com o valor "classic"

Sintaxe Abreviada dos Caminhos Locais

Abreviações podem ser usadas para descrever um caminho local.

A abreviação mais importante é que child:: pode ser omitido de um nível de localização.

Abrev. Significado Exemplo
nada child:: cd é o mesmo que child::cd
@ attribute:: cd[@type="classic"] é o mesmo que child::cd[attribute::type="classic"]
. self::node() .//cd é o mesmo que self::node()/descendant-or-self::node()/child::cd
.. parent::node() ../cd é o mesmo que parent::node()/child::cd
//// /descendant-or-self::node()/ //cd é o mesmo que /descendant-or-self::node()/child::cd

Exemplos

Exemplo Resultado
cd Seleciona todos os elementos cd que são filhos do nó atual
* Seleciona todos os elementos filhos do nó atual
text() Seleciona todos os nós textos filhos do nó atual
@src Seleciona o atributo src do nó atual
@* Seleciona todos os atributos do nó atual
cd[1] Seleciona o primeiro cd filho do nó atual
cd[last()] Seleciona o último cd filho do nó atual
*/cd Seleciona todos os cds netos do nó atual
/book/chapter[3]/para[1] Seleciona o primeiro parágrafo do terceiro capítulo do livro
//cd Seleciona todos os elementos cds descendentes da raiz do documento e assim seleciona
todos os elementos cds no mesmo documento como o nó atual
. Seleciona o nó atual
.//cd Seleciona os elementos cds descendentes do nó atual
.. Seleciona o pai do nó atual
../@src Seleciona o atributo src do pai do nó atual
cd[@type="classic"] Seleciona todos os cds filhos do nó atual que têm o atributo "type" com o valor "classic"
cd[@type="classic"][5] Seleciona o quinto cd filho do nó atual que tem o atributo "type" com o valor "classic"
cd[5][@type="classic"] Seleciona o quinto cd filho do nó atual se esse filho tem o atributo "type" com valor "classic"
cd[@type and @country ] Seleciona todos os cds filhos do nó atual que têm ambos os atributos "type" e "country"

Expressões XPath

XPath suporta expressões numéricas, de igualdade, relacionais e booleanas.

Expressões Numéricas

Expressões numéricas são usadas para realizar operações aritméticas em números.

Operador Descrição Exemplo Resultado
+ Adição 6 + 4 10
- Subtração 6 - 4 2
* Multiplicação 6 * 4 24
div Divisão 8 div 4 2
mod Módulo (resto da divisão) 5 mod 2 1

Nota: XPath sempre converte cada operando em um número antes de realizar um expressão aritmética.

Expressões de Igualdade

Expressões de igualdade são usadas para testar a igualdade entre dois valores.

Operador Descrição Exemplo Resultado
= Igual price=9.80 true (se o preço é igual a 9.80)
!= Diferente price!=9.80 false

Testando um conjunto de nós

Se é testada a igualdade do valor de teste em relação a um conjunto de nós, o resultado é verdadeiro se o conjunto de nós contém algum nó com um valor igual ao valor de teste.

Se é testada a desigualdade do valor de teste em relação a um conjunto de nós, o resultado é verdadeiro se o conjunto de nós contém algum nó com um valor diferente ao valor de teste.

O resultado é que o conjunto de nós pode ser igual e diferente ao mesmo tempo!!!

Expressões Relacionais

Expressões relacionais são usadas para comparar dois valores.

Operador Descrição Exemplo Resultado
< Menor price<9.80 false (se o preço é 9.80)
<= Menor ou igual price<=9.80 true
> Maior price>9.80 false
>= Maior ou igual price>=9.80 true

Nota: XPath sempre converte cada operando em um número antes de fazer a avaliação.

Expressões Booleanas

Expressões booleanas são usadas para comparar dois valores.

Operador Descrição Exemplo Resultado
or Ou price=9.80 or price=9.70 true (se o preço é 9.80)
and E price<=9.80 and price=9.70 false

Funções XPath

XPath contém uma biblioteca de funções para conversão de dados.

Biblioteca de Funções XPath

A biblioteca de funções XPath contém um conjunto de funções centrais para conversão e tradução de dados.

Funções para Conjunto de Nós

Nome Descrição Sintaxe
count() Retorna o número de nós num conjunto de nós number=count(node-set)
id() Seleciona elementos pelo seu ID único node-set=id(value)
last() Retorna o número da posição do último nó na lista de nós processados number=last()
local-name() Retorna a parte local de um nó. Um nó normalmente consiste de um prefixo, os dois pontos, seguidos pelo nome local string=local-name(node)
name() Retorna o nome do nó string=name(node)
namespace-uri() Retorna o namespace URI de um nó específico uri=namespace-url(node)
position() Retorna a posição na lista de nós do nó que está sendo processado atualmente number=position()

Funções de Strings

Nome Descrição Sintaxe Exemplo
concat() Retorna a concatenação de todos os argumentos string=concat(val1,val2,...) concat('The',' ','XML') -> Resultado: 'The XML'
contains() Retorna verdadeiro se a segunda string está contida dentro da primeira string, senão retorna falso bool=contains(val,substr) contains('XML','X') -> Restultado: true
normalize-space() Remove espaços antes e depois de uma string e substitui todas as seqüências internas de espaços por um único espaço em branco string=normalize-space(string) normalize-space(' The XML ') -> Resultado: 'The XML'
starts-with() Retorna verdadeiro se a primeira string começa com a segunda string, senão retorna falso bool=starts-with(string,substr) starts-with('XML','X') -> Resultado: true
string() Converte o argumento em string string(value) string(314) -> Resultado: '314'
string-length() Retorna o número de caracteres de uma string number=string-length(string) string-length('Beatles') -> Resultado: 7
substring() Retorna um pedaço da string string=substring(string,start,length) substring('Beatles',1,4) -> Resultado: 'Beat'
substring-after() Retorna a parte da string que aparece depois do argumento substr string=substring-after(string,substr) substring-after('12/10','/') -> Resultado: '10'
substring-before() Retorna a parte da string que aparece antes do argumento substr string=substring-before(string,substr) substring-before('12/10','/') -> Resultado: '12'
translate() Realiza uma substituição caracter por caracter. Ela procura no argumento 'value' os caracteres contidos na 'string1' e substitui cada caractere pelo caractere da mesma posição na 'string2' string=translate(value,string1,string2) translate('12:30','30','45') -------> Resultado: '12:45' ----------------- translate('12:30','03','54') -------> Resultado: '12:45' ----------------- translate('12:30','0123','abcd') -------> Resultado: 'bc:da'

Funções Numéricas

Nome Descrição Sintaxe Exemplo
ceiling() Retorna o menor inteiro que não é menor que o argumento (função teto) number=ceiling(number) ceiling=(3.14) -> Resultado: 4
floor() Retorna o maior inteiro que não é maior que o argumento (função chão) number=floor(number) floor(3.14) -> Resultado: 3
number() Converte o argumento em um número number=number(value) number('100') -> Resultado: 100
round() Arredonda o argumento para o inteiro mais próximo integer=round(number) round(3.14) -> Resultado: 3
sum() Retorna o valor total de um conjunto de valores numéricos num conjunto de nós number=sum(nodeset) sum(/cd/price)

Funções Booleanas

Nome Descrição Sintaxe
boolean() Converte o argumento 'value' em Booleano e retorna verdadeiro ou falso bool=boolean(value)
false() Retorna falso false() Exemplo: number(false()) -> Resultado: 0
lang() Retorna verdadeiro se o argumento 'language' é igual ao idioma do elemento xsl:lang, senão retorna falso bool=lang(language)
not() Retorna verdadeiro se o argumento 'condition' é falso, e falso se o argumento é verdadeiro bool=not(condition) Exemplo: not(false())
true() Retorna verdadeiro true() Exemplo: number(true()) -> Resultado: 1

Exemplos XPath

Nós iremos usar o catálogo de CDs do nosso tutorial de XML para demonstrar alguns exemplos XPath.

O catálogo de CDs

Se você estudou o nosso tutorial de XML você lembrará de documento XML: (Uma fração do catalogo)  

<?xml version="1.0" encoding="ISO-8859-1"?>
  <catalog>
    <cd>
      <title>Empire Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
    </cd>
    <cd>
      <title>Hide your heart</title>
      <artist>Bonnie Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
    </cd>
  .
  .
  .
  .
  </catalog>

Selecionando Nós

Nós demonstraremos como selecionar nós de um documento XML usando a função selectNodes no Internet Explorer. Esta função tem uma expressão de caminho local como argumento:

xmlobject.selectNodes(Xpath expression)

Selecionando Nós cd

O exemplo a seguir seleciona somente o primeiro nó do catálogo de cds:   xmlDoc.selectNodes("/catalog/cd[0]")

Se você tem o IE 5 ou superior você pode fazer mais testes.

Nota: IE 5 implementou que [0] deveria ser o primeiro nó, mas de acordo com o padrão W3C, deve ser [1].

Selecionando Nós price

O exemplo a seguir seleciona todos os nós price do catálogo de cds:   xmlDoc.selectNodes("/catalog/cd/price")

Se você tem o IE 5 ou superior você pode fazer mais testes.

Selecionando o texto dos Nós price

O exemplo a seguir seleciona apenas o texto dos nós price:   xmlDoc.selectNodes("/catalog/cd/price/text()")

Se você tem o IE 5 ou superior você pode fazer mais testes.

Selecionando Nós cd com price>10.80

O exemplo a seguir seleciona todos os nós cd com price>10.80:    xmlDoc.selectNodes("/catalog/cd[price>10.80]")

Se você tem o IE 5 ou superior você pode fazer mais testes.

Selecionando Nós price com price>10.80

O exemplo a seguir seleciona todos os nós price com price>10.80:   xmlDoc.selectNodes("/catalog/cd[price>10.80]/price")

E estamos conversados...

Referências:


José Carlos Macoratti