simplexml_load_string()适用于小而规整、无命名空间的XML;DOMDocument用于需修改、验证或含命名空间的XML;XMLReader专为超大文件流式解析设计,三者须按场景严格区分。

simplexml_load_string() 和 DOMDocument 是最常用、也最容易出错的两个入口。选错方法,轻则读不到属性,重则大文件直接 OOM。
用 simplexml_load_string() 解析小而规整的 XML
它把 XML 当成对象树来用,适合结构扁平、嵌套少、不带命名空间的配置类或 API 响应数据。
- 必须确保 PHP 已启用
simplexml扩展(Linux/macOS 看extension=simplexml.so,Windows 看extension=php_simplexml.dll) - 节点名含连字符(如
<user-id>)不能用$xml->user-id,得写成$xml->{'user-id'} - 属性要用
attributes()方法取:$book->attributes()->id,不是$book['id']—— 后者在某些 PHP 版本里会静默失败 - 同名子节点(如多个
<item>)必须用foreach遍历,不能直接写$xml->item[0]—— 因为SimpleXMLElement不是数组,只是支持偏移访问的特殊对象
用 DOMDocument 处理需修改、验证或带命名空间的 XML
当你需要增删节点、设置 CDATA、校验 DTD、或处理 xmlns / xmlns:xsi 这类命名空间时,DOMDocument 是唯一靠谱的选择。
- 加载后立刻关掉空白节点干扰:
$dom->preserveWhiteSpace = false,否则childNodes里全是看不见的#text节点 - 查节点别只靠
getElementsByTagName()—— 它不认命名空间;改用DOMXPath:$xpath->query('//ns:book', $context),并提前注册前缀:$xpath->registerNamespace('ns', 'http://example.com/ns') - 修改文本内容必须改
nodeValue,不是赋值给节点本身:$titleNode->nodeValue = '新标题' - 输出前加
$dom->formatOutput = true,否则saveXML()返回的是一行密文
用 XMLReader 解析几百 MB 以上的 XML 文件
别用 simplexml_load_file() 或 $dom->load() 读 200MB 的订单导出文件 —— PHP 进程内存会飙到 1.5GB 以上,然后被系统 kill。
-
XMLReader是前向只读游标,内存占用恒定在 ~100KB 左右,和文件大小无关 - 关键陷阱:调用
$reader->readOuterXml()时,当前节点必须是XMLReader::ELEMENT,且后续必须紧跟一个XMLReader::END_ELEMENT,否则会卡死或截断内容 - 不要在循环里反复
new SimpleXMLElement($xmlStr)—— 每次都触发解析开销;建议提取纯字符串后,用simplexml_load_string()解单条记录 - 遇到
XMLReader::TEXT节点时,$reader->value可能为空(比如换行或空格),要先判断trim($reader->value) !== ''
生成 XML 别硬拼字符串,优先用 SimpleXMLElement 或 DOMDocument
手写 "<book id=\"$id\">$title</book>" 看似快,但一旦内容含 <、& 或 UTF-8 特殊字符,就产生非法 XML。
立即学习“PHP免费学习笔记(深入)”;
- 用
SimpleXMLElement生成简单结构:$xml = new SimpleXMLElement('<root/>');,再链式调用addChild()和addAttribute() - 需要 CDATA、注释、处理指令(PI)或命名空间时,只能用
DOMDocument:$dom->createCDATASection()、$dom->createComment() - 所有输出前务必设编码声明:
echo $xml->asXML();默认无声明;若需<?xml version="1.0" encoding="UTF-8"?>,得用dom_import_simplexml()转成 DOM 对象再调saveXML()
simplexml_load_string()”。大文件、命名空间、动态修改、流式消费 —— 这些边界条件一旦出现,就必须切到对应工具,硬扛只会让错误在凌晨三点突然爆发。



















