SimpleXML em PHP: Um Guia Completo
SimpleXML é uma ferramenta poderosa em PHP para analisar e manipular dados XML. Aprenda a usá-la com exemplos práticos.
SimpleXML é uma extensão nativa do PHP que transforma um documento XML em uma árvore de objetos que você pode ler, percorrer e modificar com a sintaxe comum do PHP. Este tutorial cobre o carregamento de XML, a leitura de elementos e atributos, o tratamento de namespaces, a modificação de nós e a gravação do resultado — com exemplos executáveis e os erros mais comuns que enganam as pessoas.
Introdução ao SimpleXML
SimpleXML é uma extensão PHP que permite analisar e manipular dados XML com muito pouco código. Ela é distinta da extensão DOM, mas ambas são construídas sobre a mesma biblioteca libxml2, compartilhando, portanto, o seu tratamento de erros. A diferença é simples:
- SimpleXML — melhor para leitura de XML bem formado, onde você percorre principalmente uma estrutura conhecida. Acesso conciso e orientado a objetos.
- DOM — melhor para edição intensa, movimentação de nós, ou quando você precisa de controle total sobre a árvore do documento.
O SimpleXML está habilitado por padrão em compilações padrão do PHP, portanto geralmente não há nada a instalar.
Carregando XML
Existem dois pontos de entrada. Use simplexml_load_file() para um arquivo ou URL, e simplexml_load_string() para XML que você já possui em uma string (por exemplo, uma resposta de API).
Como ambas as funções dependem do libxml2, um documento malformado dispara avisos do PHP e retorna false. Sempre ative o tratamento interno de erros primeiro com libxml_use_internal_errors() para que você possa inspecionar os erros você mesmo, em vez de vazar avisos na saída:
Carregando um arquivo XML
libxml_use_internal_errors(true);
$xml = simplexml_load_file('data.xml');
if ($xml === false) {
foreach (libxml_get_errors() as $error) {
echo trim($error->message), PHP_EOL;
}
die('Failed to load XML.');
}simplexml_load_string() funciona de forma idêntica, mas recebe o texto XML diretamente:
Carregando XML a partir de uma string
$source = '<data><item><name>John Doe</name></item></data>';
$xml = simplexml_load_string($source);Em ambos os casos, o valor de retorno é um SimpleXMLElement que representa o elemento raiz do documento.
Acessando Elementos
O SimpleXML mapeia cada elemento filho como uma propriedade no objeto pai, acessada com o operador de objeto PHP -> (e não com notação de ponto — o PHP não tem acesso a membros com .). Elementos filhos repetidos são endereçados por índice. Considere este XML:
Exemplo de XML
<data>
<item>
<name>John Doe</name>
<age>30</age>
</item>
<item>
<name>Jane Doe</name>
<age>28</age>
</item>
</data>Leia o primeiro item e, em seguida, percorra todos os item com foreach:
Acessando valores de elementos
// The first <item> (index 0)
$name = $xml->item[0]->name;
$age = $xml->item[0]->age;
// Iterate through all <item> elements
foreach ($xml->item as $item) {
echo $item->name . ' is ' . $item->age . ' years old.' . PHP_EOL;
}O problema da conversão para string
$item->name não é uma string — é um SimpleXMLElement. Ele só parece uma string quando exibido com echo porque o elemento é automaticamente convertido em contextos de string. Se você armazená-lo em um array, passá-lo para json_encode(), ou compará-lo estritamente, converta-o explicitamente primeiro:
$name = (string) $xml->item[0]->name; // plain string
$age = (int) $xml->item[0]->age; // plain intLendo Atributos
Atributos de elementos são acessados com sintaxe de array, não com o operador ->. Dado <item id="1" status="active">, leia-os assim:
Acessando atributos
$id = (string) $xml->item[0]['id']; // "1"
$status = (string) $xml->item[0]['status']; // "active"
// Loop over every attribute on an element
foreach ($xml->item[0]->attributes() as $key => $value) {
echo "$key = $value" . PHP_EOL;
}Trabalhando com Namespaces
XML que usa namespaces (prefixos como <atom:link>) não será resolvido por acesso simples a propriedades — você deve registrar o namespace com children() ou usar uma consulta XPath. Esta é a razão mais comum para "o elemento estar vazio" mesmo quando está claramente no arquivo:
Elementos com namespace
$source = '<feed xmlns:atom="http://www.w3.org/2005/Atom">'
. '<atom:title>Hello</atom:title></feed>';
$xml = simplexml_load_string($source);
$atom = $xml->children('http://www.w3.org/2005/Atom');
echo (string) $atom->title; // "Hello"Consultando com XPath
Para qualquer coisa mais profunda que um filho direto, xpath() retorna um array de elementos correspondentes — muito mais limpo do que aninhar loops:
// Every <name> anywhere under the root
foreach ($xml->xpath('//name') as $name) {
echo (string) $name . PHP_EOL;
}Modificando e Adicionando Elementos
Você pode alterar um valor atribuindo à propriedade, e expandir a árvore com addChild() / addAttribute():
Modificando e construindo nós
// Change existing values
$xml->item[0]->name = 'John Smith';
$xml->item[0]->age = 32;
// Add a brand-new child element and an attribute
$new = $xml->addChild('item');
$new->addChild('name', 'New Person');
$new->addAttribute('id', '99');Atribuir um valor substitui o conteúdo de texto do elemento; addChild() acrescenta um novo elemento em vez de substituir um existente.
Convertendo de Volta para XML
Use o método asXML() para serializar a árvore (possivelmente modificada) de volta para uma string e, em seguida, gravá-la com file_put_contents():
Salvando alterações de volta em XML
file_put_contents('data.xml', $xml->asXML());Chamado sem argumento, asXML() retorna o documento completo como uma string incluindo a declaração <?xml version="1.0"?> — exatamente o que você deseja para salvar. Chame-o em um elemento filho ($xml->item[0]->asXML()) para obter apenas aquele fragmento, sem a declaração.
Conclusão
SimpleXML é a forma mais rápida de ler e editar levemente XML bem formado em PHP: carregue com simplexml_load_file() ou simplexml_load_string(), percorra a árvore com -> e indexação de array, leia atributos com [], e serialize de volta com asXML(). Lembre-se dos dois problemas recorrentes — converta elementos para strings antes de reutilizá-los, e registre namespaces antes de acessar nós com prefixo. Para edição de documentos programática e em larga escala, use a extensão DOM. Para se aprofundar, continue com PHP SimpleXML e lendo dados com SimpleXML get.