close

XPath

Ir para a navegação Ir para a pesquisa
Diagrama Sederhana XPath.png

XPath ( XML Path Language ) é uma linguagem que permite construir expressões que percorrem e processam um documento XML. A ideia é semelhante às expressões regulares para selecionar partes de um texto sem atributos ( texto simples ). XPath permite pesquisar e selecionar levando em consideração a estrutura hierárquica do XML. XPath foi criado para uso no padrão XSLT , onde é usado para selecionar e examinar a estrutura do documento de entrada da transformação. XPath foi definido pelo consórcio W3C .

Introdução

Todo o processamento realizado com um arquivo XML é baseado na possibilidade de endereçar ou acessar cada uma das partes que o compõem, para que possamos tratar cada um dos elementos de maneira diferente.

O tratamento do arquivo XML começa com a localização do mesmo em todo o conjunto de documentos existentes no mundo. Para realizar esta localização de forma inequívoca, são utilizados URIs (Uniform Resource Identifiers), dos quais os URLs (Uniform Resource Locators) são sem dúvida os mais conhecidos.

Uma vez localizado o documento XML, a forma de selecionar as informações dentro dele é através do uso de XPath, que é a abreviação do que é conhecido como XML Path Language. Com XPath podemos selecionar e referenciar textos, elementos, atributos e qualquer outra informação contida em um arquivo XML.

XPath em si é uma linguagem sofisticada e complexa, mas diferente das linguagens procedurais que costumamos utilizar (C, C++, Basic, Java...). Além disso, como quase tudo no mundo do XML, ele ainda está em desenvolvimento, por isso não é fácil encontrar ferramentas que incorporem todas as suas funcionalidades.

XPath é, por sua vez, a base sobre a qual foram especificadas novas ferramentas que o aproveitam para o tratamento de documentos XML. Ferramentas como XPointer, XLink e XQuery (a linguagem que trata documentos XML como se fosse um banco de dados). Assim, XPath é usado para dizer como uma folha de estilo deve processar o conteúdo de uma página XML, mas também para poder colocar links ou carregar áreas específicas de uma página XML em um navegador, em vez da página inteira.

O modelo de dados XPath

Um documento XML é processado por um analisador (ou analisador) construindo uma árvore de nós. Essa árvore começa com um elemento raiz, ramificando-se pelos elementos que pendem dele e terminando com nós folha, que contêm apenas texto, comentários, instruções de processamento ou até mesmo estão vazios e possuem apenas atributos.

A maneira como o XPath seleciona partes do documento XML é baseada precisamente na representação em árvore gerada do documento. De fato, os "operadores" em que consiste essa linguagem nos lembrarão da terminologia usada quando se fala em árvores na computação: raiz, filho, ancestral, descendente etc.

Um caso especial de nó são nós de atributo. Um nó pode ter quantos atributos você quiser, e um nó de atributo será criado para cada um. No entanto, esses nós de atributo NÃO são considerados seus filhos, mas sim como tags adicionadas ao nó do elemento.

Abaixo está um exemplo de como um documento XML é convertido em uma árvore. Este mesmo exemplo será usado em todo o tutorial. O documento XML é mostrado primeiro, seguido pela árvore que ele gera.

Documento XML  :

  <livro>
  
    <title>Duas por três ruas</title>
  
    <autor>Josefa Santos</autor>
  
    <capítulo num="1">
       A primeira rua
   
      <parágrafo>
        Era uma noite sombria em agosto...
      </paragraph>
    
      <paragraph highlight="yes">
         Ela, inocente como
         <link href="link">borboleta</link>
         que cruza o céu em busca de libações...
      </paragraph>
  
    </capítulo>
  
    <chapter num="2" public="yes">
      A segunda rua
  
      <parágrafo>
         Era uma noite escura em setembro...
      </paragraph>
  
      <parágrafo>
         Ela, inocente como
         <link href="link">abelha</link>
         que atravessa o vento em busca do néctar das flores...
      </paragraph>
  
    </capítulo>
  
    <apêndice num="a" public="yes">
      a terceira rua
  
      <parágrafo>
         Era uma noite densa de dezembro...
      </paragraph>
  
      <parágrafo>
         Ela, sincera como
         <link href="link">abelha</link>
         que atravessa o espaço em busca de bichos para comer...
      </paragraph>
    </apêndice>
  </book>

Árvore gerada :

/
 +---livro
       |
       +---título
       | |
       | +---(texto) Duas por três pistas
       |
       +---autor
       | |
       | +---(texto)Josefa Santos
       |
       +---capítulo [num=1]
       | |
       | +---(texto)A primeira rua
       | |
       | +---parágrafo
       | | |
       | | +---(texto)Foi uma noite sombria...
       | |     
       | +---parágrafo [destaque=sim]
       | |
       | +---(texto) Ela, que inocente
       | |
       | +---link [href=link]
       | | |
       | | +---(texto)borboleta
       | |
       | +---(texto) que cruza o céu em busca de libações...
       |
       +---capítulo [num=2, público=sim]
              |
              +---(texto)Segunda Rua
              |
              +---parágrafo
              | |
              | +---(texto) Era uma noite escura...
              |     
              +---parágrafo
                    |
                    +---(texto) Ela, como uma abelha inocente...


Tipos de nós

Existem diferentes tipos de nós em uma árvore de um documento XML, a saber: raiz, elemento, atributo, texto, comentário e instrução de processamento (respectivamente: raiz, elementos, atributo, texto, comentário e instrução de processamento). Tudo isso é muito benéfico.

Nó raiz

É identificado por /. O nó raiz não deve ser confundido com o elemento raiz do documento. Assim, se o documento XML em nosso exemplo tiver book como elemento raiz, este será o primeiro nó pendurado no nó raiz da árvore, que é: /.

Insisto: / refere-se ao nó raiz da árvore, mas não ao elemento raiz do documento XML, embora um documento XML possa ter apenas um elemento raiz. De fato, podemos dizer que o nó raiz da árvore contém o elemento raiz do documento.

Nó do elemento

Qualquer elemento em um documento XML torna-se um nó de elemento dentro da árvore. Cada elemento tem seu nó pai. O nó pai de qualquer elemento é ele próprio um elemento, exceto o elemento raiz, cujo pai é o nó raiz. Os nós elemento, por sua vez, possuem filhos, que são: nós elemento, nós texto, nós comentário e nós instruções de processamento. Os nós de elemento também possuem propriedades como seu nome, seus atributos e informações sobre os "namespaces" que eles têm ativos.

Uma propriedade interessante dos nós de elementos é que eles podem ter identificadores únicos (para isso devem ser acompanhados por uma DTD que especifique que esses atributos assumem valores únicos), o que permite referir-se a esses elementos de maneira muito mais direta.

Nós de texto

Por texto, vamos nos referir a todos os caracteres no documento que não estão marcados com uma tag. Um nó de texto não possui filhos, ou seja, os diferentes caracteres que o formam não são considerados seus filhos.

Nós de atributo

Como já indicamos, os nós de atributo não são tanto filhos do nó do elemento que os contém, mas rótulos adicionados ao referido nó do elemento. Cada nó de atributo consiste em um nome, um valor (que é sempre uma string) e um possível "namespace".

Aqueles atributos cujo valor é o valor padrão atribuído na DTD serão tratados como se o valor tivesse sido atribuído a eles ao escrever o documento XML. Ao contrário, nenhum nó é criado para atributos não especificados no documento XML e com a propriedade #IMPLIED definida em sua DTD. Além disso, nenhum nó de atributo é criado para definições de namespace. Tudo isso é normal se levarmos em conta que não é necessário ter um DTD para processar um documento XML.

Nós de instrução de comentário e processo

Além dos nós indicados, também são gerados nós na árvore para cada nó com comentários e instruções de processamento. O conteúdo desses nós pode ser acessado com a propriedade string-value .

Sintaxe e semântica (XPath 1.0)

O tipo de expressão mais importante no XPath é um caminho de localização . Um caminho de localização consiste em uma seqüência de etapas de localização . Para cada etapa de localização existem 3 componentes:

Uma expressão XPath é avaliada em relação a um nó de contexto . Um especificador de eixo como 'filho' ou 'descendente' especifica a direção para navegar a partir do nó de contexto. O nó 'teste' e o predicado são usados ​​para filtrar 'nós' específicos de acordo com o eixo específico: Por exemplo, o nó de teste 'A' requer que todos os nós para navegar tenham o rótulo ('rótulo') 'A'. Um predicado pode ser usado para especificar que os nós selecionados possuem uma propriedade específica, que é especificada pela expressão XPath.

A sintaxe XPath tem duas formas: A sintaxe abreviada é mais compacta e permite que XPaths sejam escritos e lidos de maneira fácil e intuitiva, em muitos casos usando caracteres familiares e uma maneira conhecida de construí-la. A sintaxe completa é mais sofisticada, mas permite especificar mais opções e é mais descritiva para ler, desde que você leia com atenção.

Sintaxe curta

A notação compacta permite muitos valores padrão e abreviações para os casos mais comuns. Dado o XML contendo o seguinte exemplo:

<A> 
  <B> 
    <C/> 
  </B> 
</A>

Uma seleção simples com sintaxe XPath abreviada assume uma forma como esta:

  • /A/B/C

ele seleciona o elemento C no endereço do 'filho' do elemento B que é filho do elemento A, selecionando assim o elemento mais distante do documento XML. A sintaxe XPath imita um URI ( Uniform Resource Identifier ) ​​e uma sintaxe de caminho de arquivo no estilo Unix .

Expressões mais complexas podem ser construídas usando um eixo específico diferente do eixo 'filho' padrão, um teste de nó que não possui um nome simples ou predicados, como escrever entre parênteses após qualquer etapa. Por exemplo, a expressão:

  • A//B/*[1]

seleciona o primeiro filho (' *[1]'), qualquer que seja o nome, de cada elemento B e seus filhos. Este símbolo (' //') refere-se a tomar um descendente do elemento A, ou seja, um filho do nó de contexto atual (A expressão não começa com um ' /'). Observe que o predicado [1]se vincula mais fortemente que o operador /. Para selecionar o primeiro nó selecionado usando a expressão A//B/*, digite (A//B/*)[1]. Observe que o valor do índice no predicado XPath (tecnicamente, 'próxima posição' do conjunto de nós XPath) começa em 1, não em 0, como é comum em linguagens como Javascript, C e Java.

Sintaxe expandida

Podemos escrever os dois exemplos acima na sintaxe expandida (integral) da seguinte forma:

  • /child::A/child::B/child::C
  • child::A/descendant-or-self::node()/child::B/child::node()[position()=1]

Aqui, em cada etapa do XPath, o eixo (exemplo: childo descendant-or-self) é explicitamente especificado, seguido por , ::e então o nó test , assim como Ao node()nos exemplos anteriores.

Neste mesmo, mas mais curto:

A//B/*[position()=1]

Especificador de eixo

O especificador de eixo indica a direção de navegação na árvore de representação do documento XML. Os eixos disponíveis são:

Especificadores de eixo no XPath
Sintaxe Completa Sintaxe Abreviada notas
ancestor
ancestor-or-self
attribute (SimboloArroba) (SimboloArroba)abcé a forma abreviada deattribute::abc
child xyzé uma abreviatura dechild::xyz
descendant
descendant-or-self // //é uma abreviatura de/descendant-or-self::node()/
following
following-sibling
namespace
parent .. ..é uma abreviatura deparent::node()
preceding
preceding-sibling
self . .é uma abreviatura deself::node()

Como exemplo de uso do eixo de atributo na sintaxe abreviada, ele //a/(SimboloArroba)hrefseleciona o atributo chamado hrefno elemento aem ambos os lados da árvore do documento. A expressão " ." (É uma abreviação para self::node() ) é comumente usado dentro de um predicado para se referir ao nó selecionado no momento. Por exemplo, h3[.='See also']selecione um elemento nomeado h3no contexto atual, cujo conteúdo de texto seja See also.

Teste de nó

O teste de nó pode consistir em um nome de nó específico ou em uma expressão mais geral. No caso de um documento XML no qual o prefixo do namespace gsfoi definido, ele //gs:enquiryprocurará todos os elementos enquirynesse namespace e //gs:*localizará todos os elementos, independentemente do nome local nesse namespace.

Outros formatos de teste de nó são:

Comente()
Pesquise no XML um nó de comentário, por exemplo.<!-- Comment -->
texto()
Procure um texto completo, exemplo el hello worlden<k>hello<m> world</m></k>
processamento-instrução()
Localizar XML Em instruções de processamento, por exemplo <?php echo $a; ?>. Neste caso, processing-instruction('php')vai corresponder.
não dê()
Encontre qualquer nó.

Predicados

Predicados, escritos como expressões entre colchetes, podem ser usados ​​para filtrar um conjunto de todos de acordo com alguma condição. Por exemplo, ele aretorna um conjunto de tudo (todos os elementos aque são filhos do nó de contexto) e a[(SimboloArroba)href='help.php']salva apenas os elementos que possuem o atributo hrefcom o valor help.php.

Não há limites para o número de predicados nesta etapa e eles não precisam ser limitados à última etapa de um XPath. Eles também podem ser aninhados em qualquer profundidade. Os caminhos especificados em predicados começam no contexto da etapa atual (ou seja, o teste de nó imediatamente anterior) e não alteram esse contexto. Todos os predicados devem ser satisfeitos para que uma correspondência ocorra.

Quando o valor do predicado é numérico, é açúcar sintático comparar com a posição do nó no conjunto de nós (conforme indicado pela função position()). Portanto p[1], é uma forma curta para p[position()=1]y selecionar o primeiro elemento filho p, enquanto p[last()]é uma forma curta para p[position()=last()]y selecionar o último filho pdo nó de contexto atual.

No outro caso, o valor do predicado é convertido automaticamente em um valor booleano. Quando o predicado é avaliado para um conjunto de nós, o resultado é verdadeiro quando o conjunto de nós não está vazio. Portanto p[(SimboloArroba)x]seleciona aqueles pseleciona os elementos que possuem um atributo x.

Um exemplo mais complexo é a expressão: a[/html/(SimboloArroba)lang='en'][(SimboloArroba)href='help.php'][1]/(SimboloArroba)targetseleciona o valor do atributo do targetprimeiro elemento aentre os filhos do nó de contexto que possuem o atributo hrefcom o valor help.php, desde que o elemento pai htmltenha o atributo langcom o valor en. A referência a um atributo do elemento de nível superior no primeiro predicado não afeta o contexto de outros predicados nem o da própria etapa de localização.

A ordem dos predicados é significativa se os predicados testarem a posição de um nó. Cada predicado recebe um conjunto de nós e retorna (potencialmente) um conjunto menor. Ele então a[1][(SimboloArroba)href='help.php']encontrará correspondências somente se o primeiro filho ado nó de contexto satisfizer a condição (SimboloArroba)href='help.php', desde que a[(SimboloArroba)href='help.php'][1]encontre o primeiro filho aque satisfaça a condição.

Funções e operadores

O XPath 1.0 define 4 tipos de dados: O conjunto de nós (conjuntos de nós sem ordem intrínseca), strings (String de caracteres), números (Numbers) e booleanos (Booleans).

Os operadores disponíveis são:

  • Os operadores "/", "//" e "[...]" são usados ​​nas expressões xpath, conforme descrito acima.
  • Operador de união "|", que forma a união de dois conjuntos de nós.
  • Os operadores booleanos "and" e "or", juntamente com a função "not()"
  • Operadores aritméticos "+", "-", "*", "div" (divisão) e "mod" (módulo)
  • Operador de comparação "=", "!=", "<", ">", "<=", ">="

A biblioteca de funções inclui:

  • Funções para manipular strings: concat(), substring(), contains(), substring-before(), substring-after(), translate(), normalize-space(), string-length()
  • Funções para manipular números: sum(), round(), floor(), teto()
  • Funções para obter as propriedades de um nó: name(), local-name(), namespace-uri()
  • Funções para obter as informações sobre o contexto de processamento: position(), last()
  • Funções de conversão: string(), number(), boolean()

Algumas das funções comumente usadas são descritas abaixo. [ 1 ]

Funções do conjunto de nós

posição()
Retorna um número que representa a posição do nó na sequência de nós que está sendo processada no momento (por exemplo, o nó selecionado pela instrução xsl:for-each em XSLT).
count( conjunto de nós )
retorna o número de nós no conjunto de nós que correspondem ao argumento.

Funções de string

string( objeto ?)
converte qualquer um dos 4 tipos de dados XPath em uma string de acordo com as regras de construção. Se o valor do argumento for um conjunto de nós, a função retornará um valor de string correspondente ao primeiro nó (de acordo com a ordem do documento), ignorando todos os nós futuros.
concat( string , string , string *)
concatenar 2 ou mais strings
começa com ( s1 , s2 )
retorna truese s1começar coms2
contém ( s1 , s2 )
retornar truese s1contivers2
substring( string , início , comprimento ?)
exemplo: substring("ABCDEF",2,3)retorno "BCD".
substring-antes ( s1 , s2 )
exemplo: substring-before("1999/04/01","/")retorno1999
substring-after( s1 , s2 )
exemplo: substring-after("1999/04/01","/")retorno04/01
string-comprimento(string?)
retorna o número de caracteres em uma string
normalize-space( string ?)
todos os caracteres de espaço em branco iniciais e finais serão removidos e qualquer sequência de caracteres de espaço em branco será substituída por um único espaço. Isso é muito útil quando o XML original pode ter sido formatado para Pretty-printing , o que pode tornar o processamento de strings não confiável.

Funções booleanas

não ( booleano )
nega a expressão booleana.
verdadeiro()
é avaliado como verdadeiro .
falso()
é avaliado como falso .

Funções numéricas

soma( conjunto de nós )
converte os valores de string de todos os nós encontrados pelo argumento XPath em números, de acordo com as regras de conversão internas, e retorna a soma desses números.

Exemplo de uso

Expressões podem ser criadas dentro de predicados usando os operadores: =, !=, <=, <, >=e >. Expressões booleanas podem ser combinadas com parênteses ()e operadores booleanos ande ortambém com a função not()descrita acima. O cálculo numérico pode usar *, +, -, dive mod. Strings podem consistir em caracteres Unicode .

//item[(SimboloArroba)price > 2*(SimboloArroba)discount]seleciona os itens cujo atributo de preço é maior que o dobro do valor numérico do atributo de desconto.

Conjuntos de nós inteiros podem ser combinados com o operador ( 'unioned' ) que consiste no caractere pipe |. Conjuntos de nós que satisfazem várias condições podem ser encontrados combinando as condições dentro de um predicado com ' or'.

v[x or y] | w[z]pode retornar um único conjunto de nós que consiste em todos os elementos vque possuem um elemento filho xou y, bem como todos os elementos wque possuem um elemento filho z, que foram encontrados no contexto atual.

Links externos

  1. para a descrição completa, consulte o documento de recomendação do W3C .