PHP的DOMDocument是什么 如何用它来创建和修改XML

DOMDocument是PHP操作XML/HTML的核心类,基于libxml将文档解析为内存树状结构,需显式设置encoding和version,加载用loadXML(),跨文档操作须importNode()或adoptNode(),修改文本用textContent或createTextNode(),调试需启用libxml_use_internal_errors()。

DOMDocument 是 PHP 里的 XML/HTML 文档操作核心类

它不是简单的字符串处理工具,而是把 XML 解析成内存中的树状结构(DOM),让你能像操作网页 DOM 一样增删改查节点。底层基于 libxml,所以对格式错误敏感——比如没闭合的标签、编码不匹配、BOM 头,都会直接报错或静默失败。

创建 XML 文档时必须显式设置 encoding 和 version

不设 encoding 容易在输出中文时变成乱码;不设 version 可能导致某些老系统解析异常。创建后立即调用 formatOutput = true 才能生成可读缩进,否则所有内容挤在一行。

  • DOMDocument 构造时不接受 encoding 参数,得用 saveXML() 的第二个参数或手动写声明
  • 推荐写法:
    $doc = new DOMDocument('1.0', 'UTF-8');
    $doc->formatOutput = true;
  • 如果已有 XML 字符串要加载,优先用 loadXML() 而非 load(),后者默认按文件路径处理

添加节点前必须用 importNode()adoptNode() 跨文档转移

常见错误:从一个 DOMDocument 中取节点,直接 appendChild() 到另一个文档,会报 “Wrong Document Error”。因为每个节点绑定所属文档上下文,不能硬塞。

  • 复制节点用 $newDoc->importNode($oldNode, true)true 表示深拷贝)
  • 移动节点用 $newDoc->adoptNode($oldNode)(原节点从旧文档中移除)
  • 新建元素统一走 createElement() / createElementNS(),别用字符串拼接

修改属性和文本内容要区分 setAttribute()textContent

setAttribute() 只改 attribute,textContent 替换全部子文本节点(包括注释和 CDATA),而 nodeValue 在元素节点上返回 null —— 这点容易踩坑。

  • 改属性:
    $element->setAttribute('id', 'user-123');
  • 改纯文本内容(清空原有子节点,插入新文本):
    $element->textContent = '张三';
  • 追加文本节点(保留原有子节点):
    $textNode = $doc->createTextNode('(管理员)');
    $element->appendChild($textNode);
  • 读取属性值用 $element->getAttribute('id'),不是 $element->id
DOMDocument 对命名空间、CDATA、DOCTYPE、实体引用等支持完整,但调试困难——出错时只抛 Warning 不带行号,建议始终开启 libxml_use_internal_errors(true) 并用 libxml_get_errors() 捕获具体哪一

行坏了。