W3docs

xpath()

A função SimpleXMLElement::xpath() executa consultas XPath em documentos XML com a extensão SimpleXML do PHP e retorna os nós correspondentes.

Introdução

SimpleXMLElement::xpath() executa uma consulta XPath em um documento XML carregado com a extensão SimpleXML do PHP e retorna os nós correspondentes. Sem ela, você só consegue percorrer uma árvore XML propriedade a propriedade ($xml->book->title); com ela, você pode ir diretamente a qualquer nó — independentemente de quão profundo esteja — usando uma única expressão de caminho como //book/title.

Esta página explica o que xpath() retorna, a sintaxe XPath mais usada, como ler atributos e lidar com namespaces, além dos erros comuns que costumam pegar as pessoas de surpresa.

Sintaxe

public SimpleXMLElement::xpath(string $expression): array|false
  • $expression — a expressão XPath a ser avaliada, relativa ao nó em que você a chama.
  • Retorna — um array de objetos SimpleXMLElement para cada nó correspondente, um array vazio quando nada corresponde, ou false em caso de expressão inválida.

Como o resultado é sempre um array, normalmente você o itera com foreach, mesmo quando espera apenas uma correspondência.

Um primeiro exemplo

Os exemplos abaixo usam simplexml_load_string() para que funcionem diretamente, sem nenhum arquivo externo:

<?php

$data = <<<XML
<library>
    <book genre="fiction">
        <title>The Pragmatic Programmer</title>
        <author>Hunt</author>
    </book>
    <book genre="reference">
        <title>PHP Cookbook</title>
        <author>Sklar</author>
    </book>
</library>
XML;

$xml = simplexml_load_string($data);

// Select every <title> anywhere under the root.
foreach ($xml->xpath('//title') as $title) {
    echo $title . "\n";
}

Saída:

The Pragmatic Programmer
PHP Cookbook

//title significa "qualquer elemento title em qualquer profundidade." O laço imprime cada resultado; converter um SimpleXMLElement para string (feito implicitamente pelo echo) retorna seu conteúdo de texto.

Expressões XPath comuns

ExpressãoSeleciona
/library/bookelementos book que são filhos diretos do elemento raiz library
//booktodos os elementos book, em qualquer profundidade
//book/titleo filho title de cada book
//book[1]o primeiro book (XPath é indexado a partir de 1, não de 0)
//book[@genre='fiction']livros cujo atributo genre é igual a fiction
//book[author='Sklar']livros com um filho <author> igual a Sklar
//@genretodos os nós de atributo genre

Filtrando com um predicado

Um predicado entre colchetes mantém apenas os nós que satisfazem uma condição:

<?php

$data = <<<XML
<library>
    <book genre="fiction"><title>Dune</title></book>
    <book genre="reference"><title>PHP Cookbook</title></book>
</library>
XML;

$xml = simplexml_load_string($data);

$fiction = $xml->xpath("//book[@genre='fiction']");
echo $fiction[0]->title . "\n";  // Dune
echo count($fiction) . " match\n"; // 1 match

Saída:

Dune
1 match

Ler um atributo dentro do predicado usa @, enquanto lê-lo de um nó de resultado usa sintaxe de array — (string) $book['genre']. Veja atributos para o panorama completo.

Trabalhando com namespaces XML

Se o documento declara namespaces, um caminho simples como //book não retornará nada — o parser precisa do prefixo de namespace. Registre um prefixo com registerXPathNamespace() primeiro e, em seguida, use-o na expressão:

<?php

$data = <<<XML
<lib:library xmlns:lib="http://example.com/lib">
    <lib:book><lib:title>Clean Code</lib:title></lib:book>
</lib:library>
XML;

$xml = simplexml_load_string($data);
$xml->registerXPathNamespace('l', 'http://example.com/lib');

foreach ($xml->xpath('//l:book/l:title') as $title) {
    echo $title . "\n";  // Clean Code
}

Saída:

Clean Code

O prefixo que você registra (l) é local para sua consulta — ele não precisa corresponder ao prefixo usado no documento (lib); apenas o URI do namespace precisa ser igual.

Armadilhas comuns

  • Sempre verifique o resultado. xpath() retorna false em uma expressão inválida e um array vazio quando não há correspondência. foreach (($xml->xpath($e) ?: []) as $n) protege contra os dois casos.
  • Os resultados são objetos, não strings. Converta com (string) quando precisar do texto: (string) $node.
  • XPath indexa a partir de 1. //book[1] é o primeiro livro; não existe [0].
  • O contexto importa. Chamar xpath('title') em um nó book pesquisa relativo a esse nó, enquanto um / ou // inicial pesquisa a partir da raiz do documento, independentemente de onde você o chama.

Conclusão

SimpleXMLElement::xpath() transforma a navegação profunda e repetitiva na árvore em uma única consulta declarativa. Combinado com predicados e registro de namespaces, permite identificar exatamente os nós que você precisa. Use-o com simplexml_load_string() ou com a API mais ampla do SimpleXML para ler e transformar XML em apenas algumas linhas.

Prática

Prática
Para que serve o XPath no PHP?
Para que serve o XPath no PHP?
Was this page helpful?