W3docs

PHP SimpleXML

SimpleXML is a PHP extension that provides a simple and easy-to-use API for working with XML documents. It allows PHP developers to easily parse and manipulate

Introduction

SimpleXML is a built-in PHP extension that turns an XML document into an object you can navigate with ordinary property and array syntax. Instead of walking a node tree by hand, you write $xml->book->title — the element names become properties and repeated elements become iterable lists.

This makes SimpleXML the fastest way to read a configuration file, consume an XML API response, or generate a small XML document. This page covers loading XML, reading elements and attributes, handling namespaces, querying with XPath, modifying documents, and dealing with parse errors.

SimpleXML is best for documents that fit comfortably in memory and have a known, fairly flat structure. For very large files or fine-grained, low-level control you may prefer PHP XML DOM or the Expat-based XML parser.

Loading an XML document

You build a SimpleXMLElement from one of three sources:

  • simplexml_load_string() — parse XML held in a string (handy for API responses).
  • simplexml_load_file() — parse XML stored in a file or URL.
  • new SimpleXMLElement($xml) — the constructor, which accepts a string by default.

All three return a SimpleXMLElement representing the root element of the document — not a wrapper around the whole file. So if your root is <library>, the returned object is <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); // SimpleXMLElement

Reading elements and attributes

Child elements are accessed as properties. When an element repeats (like <book>), the property behaves like a list you can index with [] or loop over with foreach. Attributes are read with array-style access ($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";
}

Output:

The Hobbit
2
The Hobbit — fiction
A Brief History of Time — science

Gotcha: an element accessed this way is a SimpleXMLElement, not a string. $book->price prints as text thanks to its __toString() method, but for arithmetic or strict comparisons cast it first: (float) $book->price or (string) $book['category']. Forgetting the cast is the most common SimpleXML bug.

Querying with XPath

For anything beyond simple navigation — filtering, searching deep in the tree, conditional selection — use xpath(). It runs an XPath expression and returns an array of matching elements.

<?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 Time

Working with namespaces

When a document uses XML namespaces, you can't reach prefixed elements with plain property access — you must call children() (for elements) or attributes() (for attributes) with the namespace URI, or register the prefix before running 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 Doe

Modifying and creating XML

SimpleXML can change existing nodes, add new ones, and serialize the result. Assign to a property to change a value, call addChild() to append an element, and addAttribute() to add an attribute. asXML() returns the document as a string, or writes it to a file when given a path.

<?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();

Output:

<?xml version="1.0"?>
<book id="42"><title>New Title</title><price>12.50</price><author>Jane Doe</author></book>

Passing a filename — $book->asXML('book.xml') — writes the document to disk instead and returns true on success. See asXML() for the full reference.

Handling parse errors

If the XML is malformed, the load functions return false and emit PHP warnings. To capture errors quietly and inspect them yourself, enable internal error handling with libxml_use_internal_errors() and read them back with 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();
}

Output:

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 1

Always check the return value before using the result — treating a false as an object causes "attempt to read property on bool" errors downstream.

Summary

  • Load XML with simplexml_load_string(), simplexml_load_file(), or new SimpleXMLElement(); the object returned is the root element.
  • Read child elements as properties and attributes as array keys; cast to (string), (int), or (float) before comparing or computing.
  • Use xpath() for filtering and deep queries, and children()/attributes() with a URI for namespaced documents.
  • Modify with property assignment, addChild(), and addAttribute(), then serialize with asXML().
  • Guard against malformed input with libxml_use_internal_errors() and libxml_get_errors().

For deeper dives, see Get node values with SimpleXML, the SimpleXML parser overview, and the lower-level libxml functions.

Practice

Practice
What is PHP SimpleXML?
What is PHP SimpleXML?
Was this page helpful?