XML SimpleXML

The shortest way to read XML: attributes, array access, namespaces and conversion.

Beginner
Key PointsSimpleXML turns elements into properties and attributes into array keys — least code for reading.

Reading

PHP
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<books>
  <book id="1"><title>PHP 入门</title><price>59</price></book>
  <book id="2"><title>PHP 进阶</title><price>79</price></book>
</books>';

$s = simplexml_load_string($xml);

foreach ($s->book as $b) {
    echo $b["id"] . " " . $b->title . " " . $b->price . "\n";
}

echo "共 " . count($s->book) . " 本\n";
echo "根元素: " . $s->getName() . "\n";
Output
1 PHP 入门 59
2 PHP 进阶 79
共 2 本
根元素: books

Elements are properties ($s->book); attributes are array keys ($b["id"]). Repeated elements become iterable collections and count() works.

Converting to arrays

SimpleXML objects are not plain objects; json_encode often surprises. Convert explicitly.

PHP
<?php
$s = simplexml_load_string($xml);

// 直接 json_encode:单个元素和多个元素结构不一致
echo json_encode($s), "\n";

// 单个字段取值要转字符串
$first = (string)$s->book[0]->title;
var_dump($first);

// 转成数组
$arr = json_decode(json_encode($s), true);
print_r($arr["book"][0]);
Output
{"book":[{"title":"PHP 入门","price":"59","@attributes":{"id":"1"}},{"title":"PHP 进阶","price":"79","@attributes":{"id":"2"}}]}
string(9) "PHP 入门"
Array
(
    [title] => PHP 入门
    [price] => 59
    [@attributes] => Array
        (
            [id] => 1
        )

)

Namespaces

Namespaced XML (RSS, SOAP, Office files) returns empty unless you declare the namespace via children().

PHP
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <item>
      <title>第一篇</title>
      <dc:creator>张三</dc:creator>
    </item>
  </channel>
</rss>';

$s = simplexml_load_string($xml);

echo (string)$s->channel->item->title, "\n";

$dc = $s->channel->item->children("dc", true);
echo (string)$dc->creator, "\n";

// 列出所有命名空间
print_r($s->getNamespaces(true));
Output
第一篇
张三
Array
(
    [dc] => http://purl.org/dc/elements/1.1/
)
The second true treats dc as a prefix rather than a URI. Omit it and you get silent empty results.

XPath

PHP
<?php
$s = simplexml_load_string($xml);

// 属性筛选
$r = $s->xpath("/books/book[@id='2']/title");
echo (string)$r[0], "\n";

// 数值比较
$r = $s->xpath("//book[price > 60]/title");
echo (string)$r[0], "\n";

// 取属性集合
$r = $s->xpath("//book/@id");
echo implode(",", array_map("strval", $r)), "\n";
Output
PHP 进阶
PHP 进阶
1,2

xpath() always returns an array (possibly empty); $r[0] on an empty array warns. Check if ($r) first.

Generating XML

PHP
<?php
$s = new SimpleXMLElement("<books></books>");

foreach ([["1", "PHP 入门", 59], ["2", "PHP 进阶", 79]] as [$id, $title, $price]) {
    $b = $s->addChild("book");
    $b->addAttribute("id", $id);
    $b->addChild("title", htmlspecialchars($title, ENT_XML1, "UTF-8"));
    $b->addChild("price", (string)$price);
}

$dom = dom_import_simplexml($s)->ownerDocument;
$dom->formatOutput = true;

echo $dom->saveXML();
Output
<?xml version="1.0"?>
<books>
  <book id="1">
    <title>PHP 入门</title>
    <price>59</price>
  </book>
  <book id="2">
    <title>PHP 进阶</title>
    <price>79</price>
  </book>
</books>

addChild does not escape — & or < produces invalid XML. Escape with htmlspecialchars(..., ENT_XML1) or switch to DOM.

Which to choose

TaskBestWhy
读几个字段SimpleXML代码最短
要改结构、删节点DOMSimpleXML 改起来别扭
几十 MB 的 XMLExpat内存恒定
要 XPath 复杂查询DOM 或 SimpleXML都支持
要严格类型和校验DOM + 手动检查SimpleXML 太宽松
SimpleXML is lenient to a fault: a missing child returns an empty object, and if ($x) is true because the object exists. Always cast to (string) before testing.

Friends & Partners