PHP SimpleXML
SimpleXML é uma extensão PHP que oferece uma API simples para trabalhar com documentos XML, facilitando a análise e manipulação.
Introdução
SimpleXML é uma extensão PHP integrada que transforma um documento XML em um objeto navegável com sintaxe comum de propriedades e arrays. Em vez de percorrer uma árvore de nós manualmente, você escreve $xml->book->title — os nomes dos elementos tornam-se propriedades e elementos repetidos tornam-se listas iteráveis.
Isso torna o SimpleXML a forma mais rápida de ler um arquivo de configuração, consumir uma resposta de API XML ou gerar um pequeno documento XML. Esta página aborda como carregar XML, ler elementos e atributos, lidar com namespaces, consultar com XPath, modificar documentos e tratar erros de análise.
O SimpleXML é mais adequado para documentos que cabem confortavelmente na memória e têm uma estrutura conhecida e razoavelmente simples. Para arquivos muito grandes ou controle de baixo nível mais detalhado, você pode preferir o PHP XML DOM ou o analisador XML baseado em Expat.
Carregando um documento XML
Você constrói um SimpleXMLElement a partir de uma de três fontes:
simplexml_load_string()— analisa XML armazenado em uma string (prático para respostas de API).simplexml_load_file()— analisa XML armazenado em um arquivo ou URL.new SimpleXMLElement($xml)— o construtor, que aceita uma string por padrão.
As três retornam um SimpleXMLElement representando o elemento raiz do documento — não um invólucro em torno do arquivo inteiro. Portanto, se sua raiz for <library>, o objeto retornado é <library>.
<?php
$data = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book category="fiction">
<title>The Hobbit</title>
<author>J.R.R. Tolkien</author>
<price>14.99</price>
</book>
<book category="science">
<title>A Brief History of Time</title>
<author>Stephen Hawking</author>
<price>18.50</price>
</book>
</library>
XML;
$library = simplexml_load_string($data);
echo get_class($library); // SimpleXMLElementLendo elementos e atributos
Elementos filhos são acessados como propriedades. Quando um elemento se repete (como <book>), a propriedade se comporta como uma lista que pode ser indexada com [] ou percorrida com foreach. Atributos são lidos com acesso estilo array ($element['attr']).
<?php
$library = simplexml_load_string($data); // the XML from above
echo $library->book[0]->title . "\n"; // The Hobbit
echo count($library->book) . "\n"; // 2
foreach ($library->book as $book) {
echo $book->title . " — " . $book['category'] . "\n";
}Saída:
The Hobbit
2
The Hobbit — fiction
A Brief History of Time — scienceAtenção: um elemento acessado dessa forma é um
SimpleXMLElement, não uma string.$book->priceé impresso como texto graças ao seu método__toString(), mas para aritmética ou comparações estritas, converta primeiro:(float) $book->priceou(string) $book['category']. Esquecer a conversão é o erro mais comum com o SimpleXML.
Consultando com XPath
Para qualquer coisa além de uma navegação simples — filtragem, busca em profundidade na árvore, seleção condicional — use xpath(). Ele executa uma expressão XPath e retorna um array de elementos correspondentes.
<?php
$library = simplexml_load_string($data);
// Titles of books priced over 10
foreach ($library->xpath('//book[price>10]/title') as $title) {
echo $title . "\n";
}
// The Hobbit
// A Brief History of TimeTrabalhando com namespaces
Quando um documento usa namespaces XML, você não pode acessar elementos prefixados com acesso simples de propriedade — é necessário chamar children() (para elementos) ou attributes() (para atributos) com o URI do namespace, ou registrar o prefixo antes de executar o XPath.
<?php
$rss = <<<XML
<rss xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<item>
<title>Hello</title>
<dc:creator>Jane Doe</dc:creator>
</item>
</channel>
</rss>
XML;
$xml = simplexml_load_string($rss);
$item = $xml->channel->item;
// Access the dc: namespace by URI
$dc = $item->children('http://purl.org/dc/elements/1.1/');
echo $dc->creator . "\n"; // Jane DoeModificando e criando XML
O SimpleXML pode alterar nós existentes, adicionar novos e serializar o resultado. Atribua um valor a uma propriedade para alterá-la, chame addChild() para acrescentar um elemento e addAttribute() para adicionar um atributo. asXML() retorna o documento como uma string ou o salva em um arquivo quando um caminho é fornecido.
<?php
$book = simplexml_load_string('<book><title>Old Title</title><price>10.00</price></book>');
$book->title = 'New Title'; // change an existing value
$book->price = '12.50';
$book->addChild('author', 'Jane Doe'); // add a new element
$book->addAttribute('id', '42'); // add an attribute
echo $book->asXML();Saída:
<?xml version="1.0"?>
<book id="42"><title>New Title</title><price>12.50</price><author>Jane Doe</author></book>Passar um nome de arquivo — $book->asXML('book.xml') — salva o documento em disco e retorna true em caso de sucesso. Consulte asXML() para a referência completa.
Tratando erros de análise
Se o XML estiver malformado, as funções de carregamento retornam false e emitem avisos do PHP. Para capturar os erros silenciosamente e inspecioná-los por conta própria, habilite o tratamento de erros interno com libxml_use_internal_errors() e leia-os de volta com libxml_get_errors().
<?php
libxml_use_internal_errors(true);
$broken = "<library><book><title>Unclosed</book></library>";
$xml = simplexml_load_string($broken);
if ($xml === false) {
echo "Failed to parse XML:\n";
foreach (libxml_get_errors() as $error) {
echo trim($error->message) . "\n";
}
libxml_clear_errors();
}Saída:
Failed to parse XML:
Opening and ending tag mismatch: title line 1 and book
Opening and ending tag mismatch: book line 1 and library
Premature end of data in tag library line 1Sempre verifique o valor de retorno antes de usar o resultado — tratar um false como objeto causa erros de "tentativa de ler propriedade em bool" posteriormente.
Resumo
- Carregue XML com
simplexml_load_string(),simplexml_load_file()ounew SimpleXMLElement(); o objeto retornado é o elemento raiz. - Leia elementos filhos como propriedades e atributos como chaves de array; converta para
(string),(int)ou(float)antes de comparar ou calcular. - Use
xpath()para filtragem e consultas profundas, echildren()/attributes()com um URI para documentos com namespaces. - Modifique com atribuição de propriedade,
addChild()eaddAttribute(), depois serialize comasXML(). - Proteja-se contra entradas malformadas com
libxml_use_internal_errors()elibxml_get_errors().
Para mais detalhes, consulte Obter valores de nós com SimpleXML, a visão geral do analisador SimpleXML e as funções libxml de baixo nível.