PHP SimpleXML - Get

Su Subhalakshmi Chandran Updated 21 Oct 2026
5 min read ·Lesson 180 of 185
In this post

Getting Data Out of XML Documents In simple terms: Real XML documents are rarely as tidy as simple examples. You may need the third item, all elements matching a condition, every attribute of an eleme

Getting Data Out of XML Documents

In simple terms: Real XML documents are rarely as tidy as simple examples. You may need the third item, all elements matching a condition, every attribute of an element, elements whose names you do not know in advance, or data hidden behind namespaces (prefixes like dc: or g:). SimpleXML provides tools for all of these.

Technically: Beyond property and array access (see PHP SimpleXML Parser), SimpleXMLElement offers children(), attributes(), getName(), count(), and xpath(). XPath is a query language for selecting nodes in an XML tree. Namespaced content is accessed by passing the namespace to children()/attributes() or by registering it for XPath.

The examples use the catalog document from PHP XML Parsers ($catalogXml).


Accessing Elements by Position

<?php
$catalog = simplexml_load_string($catalogXml);

echo $catalog->product[0]->name . "\n";   // first product
echo $catalog->product[2]->name . "\n";   // third product
echo count($catalog->product) . " products\n";

$last = $catalog->product[count($catalog->product) - 1];
echo "Last: {$last->name}\n";

Output

Gel Pen
Wireless Mouse
3 products
Last: Wireless Mouse

Indexes are zero-based. A non-existent index (such as product[5]) returns null-like empty results, so check with isset($catalog->product[5]) before using it.


Iterating Unknown Children and Attributes

When element names are not known in advance — for example, to convert or display any record — iterate with children() and attributes():

<?php
$catalog = simplexml_load_string($catalogXml);
$product = $catalog->product[0];

echo "Element: " . $product->getName() . "\n";

foreach ($product->attributes() as $name => $value) {
    echo "  @$name = $value\n";
}

foreach ($product->children() as $child) {
    echo "  {$child->getName()} = $child\n";
}

Output

Element: product
  @sku = PEN-01
  @category = stationery
  name = Gel Pen
  price = 20.00
  stock = 120
  • attributes() yields attribute names (as keys) and values.
  • children() yields all child elements; getName() returns each tag name.
  • With this, a generic function can convert any flat record into an array:
function recordToArray(SimpleXMLElement $record): array
{
    $data = [];
    foreach ($record->attributes() as $name => $value) {
        $data[$name] = (string) $value;
    }
    foreach ($record->children() as $child) {
        $data[$child->getName()] = (string) $child;
    }
    return $data;
}

Searching With XPath

XPath selects nodes with path expressions, similar to file paths, plus conditions in square brackets:

<?php
$catalog = simplexml_load_string($catalogXml);

$electronics = $catalog->xpath('//product[@category="electronics"]/name');
echo "Electronics: " . implode(', ', array_map('strval', $electronics)) . "\n";

$expensive = $catalog->xpath('//product[price > 500]/@sku');
echo "Over ₹500: " . implode(', ', array_map('strval', $expensive)) . "\n";

$lowStock = $catalog->xpath('//product[stock < 10]');
echo "Low stock: {$lowStock[0]->name} ({$lowStock[0]->stock} left)\n";

Output

Electronics: Desk Lamp, Wireless Mouse
Over ₹500: LAMP-01, MOUSE-01
Low stock: Desk Lamp (6 left)

XPath Essentials

ExpressionSelects
/catalog/product<product> children of the root <catalog>
//nameAll <name> elements anywhere in the document
//product[@category="electronics"]Products with that attribute value
//product[price > 500]Products whose <price> is greater than 500 (compared numerically)
//product/@skuThe sku attributes of all products
//product[1]The first product (XPath positions start at 1)
//product[last()]The last product
//product[contains(name, "Lamp")]Products whose name contains "Lamp"

xpath() always returns an array of SimpleXMLElement objects (empty if nothing matches, false on an invalid expression). array_map('strval', ...) converts the results to strings.

Security note: Never insert user input directly into XPath expressions — this enables XPath injection, similar to SQL injection. Validate input strictly (for example, allow only [A-Z0-9-] for SKUs) or filter the results in PHP instead.


Working With Namespaces

Many real-world formats use namespaces. RSS feeds often include elements from the Dublin Core vocabulary, such as <dc:creator>:

<?php
$rss = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>GoCourse Blog</title>
    <item>
      <title>PHP 8.5 Released</title>
      <link>https://gocourse.in/blog/php-8-5</link>
      <pubDate>Thu, 20 Nov 2025 09:00:00 +0530</pubDate>
      <dc:creator>Asha</dc:creator>
    </item>
    <item>
      <title>Learning SimpleXML</title>
      <link>https://gocourse.in/blog/simplexml</link>
      <pubDate>Thu, 15 Oct 2026 10:30:00 +0530</pubDate>
      <dc:creator>Bala</dc:creator>
    </item>
  </channel>
</rss>
XML;

$feed = simplexml_load_string($rss);

echo $feed->channel->title . "\n";

foreach ($feed->channel->item as $item) {
    $author = $item->children('http://purl.org/dc/elements/1.1/')->creator;
    $date = DateTimeImmutable::createFromFormat(DATE_RSS, (string) $item->pubDate);

    echo "- {$item->title} by $author, {$date->format('d M Y')}\n";
}

Output

GoCourse Blog
- PHP 8.5 Released by Asha, 20 Nov 2025
- Learning SimpleXML by Bala, 15 Oct 2026

How It Works

  1. $item->creator would find nothing, because <dc:creator> belongs to a different namespace.
  2. children('http://purl.org/dc/elements/1.1/') switches to that namespace; the namespace URI identifies it reliably. (Passing the prefix with children('dc', true) also works, but prefixes may differ between documents, while URIs do not.)
  3. RSS dates use the RFC 2822 format, which DATE_RSS describes; createFromFormat() turns them into date objects for reformatting (see Date Formatting).

Default Namespaces and XPath

Documents such as sitemaps declare a default namespace (<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">). Property access works as usual, but XPath queries need the namespace registered with a prefix:

<?php
$sitemap = simplexml_load_string(<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url><loc>https://gocourse.in/</loc></url>
  <url><loc>https://gocourse.in/php/</loc></url>
</urlset>
XML);

$sitemap->registerXPathNamespace('s', 'http://www.sitemaps.org/schemas/sitemap/0.9');

foreach ($sitemap->xpath('//s:loc') as $loc) {
    echo $loc . "\n";
}

Output

https://gocourse.in/
https://gocourse.in/php/

Without the registration, xpath('//loc') returns an empty array — a very common source of confusion.


Converting to Arrays: A Caution

A popular shortcut converts SimpleXML to arrays with json_decode(json_encode($xml), true). It works for simple documents but has pitfalls:

  • A single child becomes a value, while several children become a list — the structure changes depending on the data.
  • Attributes end up under a special @attributes key.
  • Namespaced elements are silently dropped.
  • Empty elements become empty arrays instead of empty strings.

For reliable results, convert explicitly with functions like recordToArray() above.


Common Mistakes

Expecting XPath Positions to Start at 0

Effect: //product[0] selects nothing.

Fix: XPath positions start at 1; PHP array indexes start at 0.

Forgetting That xpath() Returns an Array

Effect: $catalog->xpath('//name')->name fails.

Fix: Loop over the result or use [0] after checking it is not empty.

Ignoring Namespaces

Effect: Elements such as <dc:creator> or sitemap <loc> seem to be missing.

Fix: Use children($namespaceUri) and registerXPathNamespace().

Building XPath Queries From User Input

Effect: XPath injection.

Fix: Validate input strictly or filter results in PHP.


Best Practices

  • Use children(), attributes(), and getName() for generic processing.
  • Use XPath for searches with conditions instead of nested loops.
  • Identify namespaces by their URI, and register them for XPath queries.
  • Convert results into explicitly typed PHP arrays or objects.
  • Treat all data read from external XML as untrusted input.

Official reference: https://www.php.net/manual/en/simplexml.examples-basic.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning MySQL Database MySQL Connect MySQL Create DB MySQL Create Table MySQL Insert Data MySQL Get Last ID MySQL Insert Multiple MySQL Prepared MySQL Select Data MySQL Where Debugging PHP Project: Image Upload Gallery $_SESSION $_ENV PHP RegEx RegEx Patterns Heredoc and Nowdoc RegEx Modifiers preg_match preg_replace preg_split PHP RegEx Functions Nullable Types Mixed and Never Types Nullsafe Operator PHP Attributes PHP Fibers Readonly Classes Property Hooks (PHP 8.4) Asymmetric Visibility (PHP 8.4) Reflection API SPL Data Structures Composer PHP Form Handling PDO Transactions PDO Error Handling PHP XML Parsers PHP SimpleXML Parser PHP SimpleXML - Get PHP XML Expat Parser PHP DOM Parser PHP XMLReader PHP XMLWriter AJAX Intro
Ask about this post
AI Ask about this post

Ask questions about PHP SimpleXML - Get and get answers drawn from it.

Signed-in readers only.