使用PHP的DOMDocument类向现有XML追加节点时报错如何解决?
问题排查与解决方案
存在的问题
你代码里有三处导致报错的问题:
- 低级语法错误:循环中调用
$root->appendChild(item);时,变量名前遗漏了$符号,应该传入$item。 - 节点创建方式错误:直接通过
new DOMElement创建的节点不属于当前加载XML的DOMDocument实例,直接追加会触发节点归属异常,部分环境下会导致操作失败$root被置为null。 - 多余操作与缺少异常校验:加载XML文件后多余调用
$file->loadXML($file->saveXML())属于无意义操作,同时你没有校验XML文件是否加载成功,如果文件路径错误、不可读或者格式损坏,获取root节点时会返回null,调用appendChild就会触发你收到的报错。
你收到的报错信息:
Fatal error: Uncaught Error: Call to a member function appendChild() on null in C:\Users\pfort\Desktop\p.php:12 Stack trace: #0 {main} thrown in C:\Users\user_acer\Desktop\p.php on line 12
正确实现代码
<?php // 初始化DOM对象 $file = new DOMDocument; // 开启错误捕获,避免加载XML失败直接抛出notice libxml_use_internal_errors(true); // 加载XML文件,判断是否加载成功 if (!$file->load("xml.xml")) { // 加载失败的错误处理逻辑 foreach (libxml_get_errors() as $error) { echo "XML加载错误:" . $error->message . "<br>"; } libxml_clear_errors(); exit; } libxml_clear_errors(); // 获取root节点 $root = $file->getElementsByTagName('root')->item(0); if (!$root) { echo "未找到root节点"; exit; } // 循环添加节点 foreach (["Foo_1", "Bar_2", "Foo_3", "Bar_4"] as $val) { // 用当前DOMDocument的createElement方法创建节点,保证节点归属正确 $item = $file->createElement('item'); $name = $file->createElement('name', $val); $item->appendChild($name); $root->appendChild($item); } // 格式化输出配置,保存后的XML会保持缩进格式 $file->formatOutput = true; // 保存修改到原文件 $file->save("xml.xml"); ?>
代码说明
- 新增了XML加载校验逻辑,避免文件不存在、格式错误导致的后续异常
- 使用
DOMDocument::createElement方法创建节点,保证节点属于当前文档实例,避免归属错误 - 移除了多余的
loadXML操作,加载文件后直接操作节点即可 - 新增格式化输出配置,保存后的XML会保持缩进格式,不会挤成一行
内容的提问来源于stack exchange,提问作者Petr Fořt Fru-Fru
相关产品推荐
相关产品推荐

