Skip to content

PHP SimpleXML - 获取

SimpleXML 是 PHP 内置的扩展,它提供了一种直观的方式来解析和操作 XML 数据。它将 XML 文档表示为一个对象,使得数据访问变得直接。

虽然 SimpleXML 对于基本的 XML 任务很方便,但对于复杂的操纵或非常大的文件,请考虑使用 DOMDocument 或 XMLReader 扩展。

要读取 XML 文件,请使用 simplexml_load_file() 函数。成功时,它返回一个 SimpleXMLElement 对象;失败时,返回 false。在继续之前,务必检查返回值。

考虑这个简单的 XML 文件,note.xml:

<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

以下是如何从 note.xml 获取节点值:

<?php
declare(strict_types=1);
$xmlFilePath = "note.xml";
if (!file_exists($xmlFilePath)) {
echo "Error: File not found ({$xmlFilePath})";
exit;
}
// Load the XML file
// 加载 XML 文件
$xml = simplexml_load_file($xmlFilePath);
// Check if loading was successful
// 检查是否加载成功
if ($xml === false) {
echo "Error: Cannot create SimpleXMLElement object.";
// You might want to log specific XML errors here using libxml_get_errors()
// 你可能想在这里使用 libxml_get_errors() 记录特定的 XML 错误
// libxml_use_internal_errors(true);
// $xml = simplexml_load_file(...);
// if ($xml === false) { foreach(libxml_get_errors() as $error) { echo $error->message; } }
exit;
}
// Access node values as object properties
// 将节点值作为对象属性访问
// Casting to string is often implicit but good for clarity
// 转换为字符串通常是隐式的,但明确指出有助于提高可读性
echo (string)$xml->to . "<br>";
echo (string)$xml->from . "<br>";
echo (string)$xml->heading . "<br>";
echo (string)$xml->body;
?>

上面代码的预期输出是:

Tove
Jani
Reminder
Don’t forget me this weekend!

让我们使用一个更复杂的 XML 文件 books.xml 来进行进一步的示例:

Everyday Italian Giada De Laurentiis 2005 30.00 Harry Potter J. K. Rowling 2005 29.99 XQuery Kick Start James McGovern 2003 49.99 Learning XML Erik T. Ray 2003 39.95

当多个元素共享同一个名称(如 <book>)时,SimpleXML 将它们视为一个可通过类似数组的索引表示法访问的可迭代集合。

此示例检索第一个(索引 0)和第二个(索引 1)<book> 元素的 <title>:

<?php
declare(strict_types=1);
$xmlFilePath = "books.xml";
if (!file_exists($xmlFilePath)) {
die("Error: File not found ({$xmlFilePath})");
}
$xml = simplexml_load_file($xmlFilePath);
if ($xml === false) {
die("Error: Cannot create object");
}
// Check if book elements exist before accessing
// 访问前检查 book 元素是否存在
if (isset($xml->book[0])) {
echo (string)$xml->book[0]->title . "<br>";
}
if (isset($xml->book[1])) {
echo (string)$xml->book[1]->title;
}
?>

预期输出是:

Everyday Italian
Harry Potter

您可以使用 foreach 循环轻松迭代同名元素。可以使用 children() 方法,但通常直接迭代父属性也能工作。

此示例遍历所有 <book> 元素并打印它们的详细信息:

<?php
declare(strict_types=1);
$xmlFilePath = "books.xml";
if (!file_exists($xmlFilePath)) {
die("Error: File not found ({$xmlFilePath})");
}
$xml = simplexml_load_file($xmlFilePath);
if ($xml === false) {
die("Error: Cannot create object");
}
// Iterate directly over the <book> elements
// 直接迭代 <book> 元素
foreach ($xml->book as $book) {
echo htmlspecialchars((string)$book->title, ENT_QUOTES, 'UTF-8') . ", ";
echo htmlspecialchars((string)$book->author, ENT_QUOTES, 'UTF-8') . ", ";
echo htmlspecialchars((string)$book->year, ENT_QUOTES, 'UTF-8') . ", ";
echo htmlspecialchars((string)$book->price, ENT_QUOTES, 'UTF-8') . "<br>";
}
?>

注意:我们在这里使用 htmlspecialchars() 函数在 HTML 上下文中安全地输出文本内容,以防止 XML 数据来自不可信来源时潜在的跨站脚本攻击 (XSS)。

预期输出是:

Everyday Italian, Giada De Laurentiis, 2005, 30.00
Harry Potter, J. K. Rowling, 2005, 29.99
XQuery Kick Start, James McGovern, 2003, 49.99
Learning XML, Erik T. Ray, 2003, 39.95

使用类似数组的表示法来访问元素对象上的属性。

此示例获取第一个 <book> 的 category 属性以及第二个 <book> 中 <title> 元素的 lang 属性:

<?php
declare(strict_types=1);
$xmlFilePath = "books.xml";
if (!file_exists($xmlFilePath)) {
die("Error: File not found ({$xmlFilePath})");
}
$xml = simplexml_load_file($xmlFilePath);
if ($xml === false) {
die("Error: Cannot create object");
}
// Access attributes using array notation
// 使用数组表示法访问属性
if (isset($xml->book[0]['category'])) {
echo (string)$xml->book[0]['category'] . "<br>";
}
if (isset($xml->book[1]->title['lang'])) {
echo (string)$xml->book[1]->title['lang'];
}
?>

预期输出是:

COOKING
en

您可以结合遍历元素和访问它们的属性。

此示例从每个 <book> 的 <title> 元素中检索 lang 属性:

<?php
declare(strict_types=1);
$xmlFilePath = "books.xml";
if (!file_exists($xmlFilePath)) {
die("Error: File not found ({$xmlFilePath})");
}
$xml = simplexml_load_file($xmlFilePath);
if ($xml === false) {
die("Error: Cannot create object");
}
foreach ($xml->book as $book) {
// Check if the lang attribute exists before accessing
// 访问前检查 lang 属性是否存在
if (isset($book->title['lang'])) {
echo htmlspecialchars((string)$book->title['lang'], ENT_QUOTES, 'UTF-8');
} else {
echo "(no lang attribute)"; // Handle cases where attribute might be missing
// (没有 lang 属性) // 处理属性可能缺失的情况
}
echo "<br>";
}
?>

预期输出是:

en
en
en-us
en-us

有关 SimpleXML 函数及其用法的全面详细信息,请查阅官方 PHP 手册:https://www.php.net/manual/en/book.simplexml.php