W3docs

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 int

Lendo 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.

Prática

Prática
O que a extensão SimpleXML em PHP faz?
O que a extensão SimpleXML em PHP faz?
Was this page helpful?