PHP SimpleXML Parser
What Is SimpleXML? In simple terms: SimpleXML turns an XML document into PHP objects that you can navigate naturally: child elements become properties ( $product->name ), attributes are read like a
What Is SimpleXML?
In simple terms: SimpleXML turns an XML document into PHP objects that you can navigate naturally: child elements become properties ($product->name), attributes are read like array keys ($product['sku']), and repeated elements can be looped over with foreach. For most everyday XML tasks, it is the quickest and most readable tool.
Technically: The SimpleXML extension (enabled by default) parses a document into a tree of SimpleXMLElement objects. Property access, array access, iteration, and casting are mapped to XML operations. SimpleXML can also make simple modifications and save the document. It is built on libxml, so it shares that library's parsing rules, error handling, and security defaults.
The examples use the catalog document from PHP XML Parsers, stored in $catalogXml.
Loading XML
| Function / Constructor | Loads From |
|---|---|
simplexml_load_string($xml) | A string |
simplexml_load_file($path) | A file (or URL, if allowed) |
new SimpleXMLElement($xml) | A string; throws an Exception on invalid XML |
<?php
$catalog = simplexml_load_string($catalogXml);
if ($catalog === false) {
exit("Invalid XML\n");
}
echo $catalog->getName() . "\n";
echo $catalog['store'] . " (updated " . $catalog['updated'] . ")\n";
Output
catalog
GoCourse Shop (updated 2026-10-15)
The returned object represents the root element (<catalog>); you do not write $catalog->catalog. getName() returns the element's tag name, and $catalog['store'] reads an attribute.
Reading Elements and Attributes
<?php
$catalog = simplexml_load_string($catalogXml);
foreach ($catalog->product as $product) {
printf(
"%-9s %-15s ₹%8s %3d in stock [%s]\n",
$product['sku'],
$product->name,
$product->price,
(int) $product->stock,
$product['category']
);
}
Output
PEN-01 Gel Pen ₹ 20.00 120 in stock [stationery]
LAMP-01 Desk Lamp ₹ 1299.00 6 in stock [electronics]
MOUSE-01 Wireless Mouse ₹ 599.00 30 in stock [electronics]
How It Works
| Syntax | Meaning |
|---|---|
$catalog->product | All <product> children of <catalog> |
foreach ($catalog->product as $product) | Loop over each <product> |
$catalog->product[1] | The second <product> (zero-based) |
$product->name | The <name> child element |
$product['sku'] | The sku attribute |
$product->price['currency'] | An attribute of a child element |
$catalog->product without an index behaves like the first matching element when used as a single value, and like a list when used with foreach or count().
Values Are Objects — Cast Them
Every element and attribute is a SimpleXMLElement object, not a string or number:
<?php
$catalog = simplexml_load_string($catalogXml);
$stock = $catalog->product[0]->stock;
echo get_class($stock) . "\n";
var_dump((int) $stock);
var_dump((string) $catalog->product[0]->name);
$totalUnits = 0;
$stockValue = 0.0;
foreach ($catalog->product as $product) {
$totalUnits += (int) $product->stock;
$stockValue += (float) $product->price * (int) $product->stock;
}
echo "Units: $totalUnits, stock value: ₹" . number_format($stockValue, 2) . "\n";
Output
SimpleXMLElement
int(120)
string(7) "Gel Pen"
Units: 156, stock value: ₹28,164.00
Why Casting Matters
echoand string interpolation convert elements to strings automatically, which is why printing works without casts.- Arithmetic, comparisons, array keys, JSON encoding, and storing values in sessions or databases need explicit casts:
(string),(int),(float). - Comparing objects without casting gives surprising results:
$product['category'] === 'electronics'is alwaysfalse, because the left side is an object. Write(string) $product['category'] === 'electronics'.
Checking Whether Elements Exist
<?php
$catalog = simplexml_load_string($catalogXml);
$product = $catalog->product[0];
var_dump(isset($product->name));
var_dump(isset($product->discount));
var_dump(isset($product['sku']));
echo "Discount: '" . $product->discount . "'\n";
Output
bool(true)
bool(false)
bool(true)
Discount: ''
Accessing a missing element does not cause an error — it returns an empty element that converts to an empty string. Use isset() to distinguish "missing" from "empty".
Creating and Modifying XML
SimpleXML can add elements and attributes and output the document with asXML():
<?php
$order = new SimpleXMLElement('<order/>');
$order->addAttribute('id', '501');
$item = $order->addChild('item');
$item->addAttribute('sku', 'PEN-01');
$item->addChild('quantity', '10');
$order->note = 'Deliver after 5 PM & call first';
echo $order->asXML();
Output
<?xml version="1.0"?>
<order id="501"><item sku="PEN-01"><quantity>10</quantity></item><note>Deliver after 5 PM & call first</note></order>
How It Works
new SimpleXMLElement('<order/>')creates a document with an empty root element.addAttribute()andaddChild()add attributes and child elements;addChild()returns the new element, so it can receive its own children.- Assigning to a property (
$order->note = ...) creates or replaces a child element, and escapes special characters:&became&. asXML()returns the document as a string (or writes it to a file when given a filename). The output is compact, without indentation; use DOM'sformatOutputfor pretty-printed XML (see PHP DOM Parser).
Warning: The second argument of
addChild()is not fully escaped:$order->addChild('note', 'Tom & Jerry')triggers an "unterminated entity reference" warning and truncates the text. Assign through a property, or escape the value withhtmlspecialchars()first.
Changing and Removing
$catalog->product[1]->stock = 5; // change an element's text
$catalog->product[1]['category'] = 'home'; // change an attribute
unset($catalog->product[2]); // remove the third product
For complex edits (inserting elements at specific positions, moving nodes), DOM offers more control.
Practical Example: Reading a Supplier Price List
<?php
$supplierXml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<pricelist supplier="Classmate Stationers">
<item code="PEN-01"><cost>12.50</cost><moq>100</moq></item>
<item code="NB-A5"><cost>38.00</cost><moq>50</moq></item>
<item code="INK-09"><cost>8.75</cost></item>
</pricelist>
XML;
libxml_use_internal_errors(true);
$list = simplexml_load_string($supplierXml);
if ($list === false) {
exit("Supplier file is not valid XML\n");
}
$costs = [];
foreach ($list->item as $item) {
$code = (string) $item['code'];
$costs[$code] = [
'cost_paise' => (int) round((float) $item->cost * 100),
'minimum_order' => isset($item->moq) ? (int) $item->moq : 1,
];
}
echo "Supplier: {$list['supplier']}\n";
print_r($costs['INK-09']);
echo json_encode($costs) . "\n";
Output
Supplier: Classmate Stationers
Array
(
[cost_paise] => 875
[minimum_order] => 1
)
{"PEN-01":{"cost_paise":1250,"minimum_order":100},"NB-A5":{"cost_paise":3800,"minimum_order":50},"INK-09":{"cost_paise":875,"minimum_order":1}}
Step-by-Step Explanation
- Parse errors are collected, and an invalid file stops the import cleanly.
- Each
<item>is converted into a plain PHP array with typed values: the code as a string, the cost in integer paise, and the minimum order quantity as an integer. - A missing
<moq>element (forINK-09) falls back to 1 viaisset(). - After conversion, the data no longer contains
SimpleXMLElementobjects, so it can be JSON-encoded, stored, or compared safely.
Common Mistakes
Forgetting to Cast Values
Effect: Failed strict comparisons, objects stored instead of values, odd JSON output.
Fix: Cast with (string), (int), or (float) when extracting data.
Including the Root Element in the Path
Effect: $catalog->catalog->product finds nothing.
Fix: The loaded object is the root element.
Using addChild() With Unescaped &
Effect: Warnings and truncated text.
Fix: Assign through properties or escape the value.
Not Checking for Parse Failures
Effect: false is used as an object.
Fix: Check the result and use libxml_use_internal_errors().
Best Practices
- Use SimpleXML for straightforward reading of small and medium XML documents.
- Cast every extracted value to a proper PHP type.
- Use
isset()to test for optional elements and attributes. - Convert XML into arrays or objects of your own early, and work with those.
- Switch to DOM for complex edits and to XMLReader for very large files.
Official reference: https://www.php.net/manual/en/book.simplexml.php