PHP 8.1中如何将XML文件追加到指定XML元素节点下
问题说明
- 现有基础XML文件
Book.xml,结构如下:
<?xml version="1.0" encoding ="utf-8"?> <School> <Class type="Math"> <TITLE>Match 101</TITLE> </Class> <Class type="English"> <TITLE>English 102</TITLE> </Class> <Students type="Secondary"> <Student> </Student> </Students> <Grade> </Grade> </School>
- 需求:将
edit.xml存储的<Teachers></Teachers>节点,插入到Students节点之后、Grade节点之前的位置,edit.xml内容如下:
<Teachers> </Teachers>
- 运行环境为PHP 8.1,自行编写的代码执行后,新节点被追加到整个XML文件末尾,不符合预期,错误代码如下:
$readfile = new class extends DOMDocument { public function __invoke(string $path): DOMDocumentFragment { return @($_ = $this->createDocumentFragment()) ->appendXML(file_get_contents($path)) ? $_ : null; } }; $readfile->load(__DIR__ . '/Book.xml'); $readfile->append($import(__DIR__ . '/edit.xml')); $readfile->save('output.xml');
- 预期输出的
output.xml结构:
<?xml version="1.0" encoding ="utf-8"?> <School> <Class type="Math"> <TITLE>Match 101</TITLE> </Class> <Class type="English"> <TITLE>English 102</TITLE> </Class> <Students type="Secondary"> <Student> </Student> </Students> <Teachers> </Teachers> <Grade> </Grade> </School>
错误原因
原有代码存在两个核心问题:
- 直接调用DOMDocument实例的
append()方法添加节点,只会把新节点追加到文档节点的子节点末尾,无法自定义插入位置 - 代码中
$import变量未定义,本身存在逻辑错误
要实现指定位置插入,核心是先定位参考节点:要把新节点放在Students节点之后,只需要将新节点插入到Students的下一个兄弟节点(即Grade节点)之前即可,这个操作可以通过父节点的insertBefore()方法实现。
可直接运行的正确代码
$dom = new DOMDocument('1.0', 'utf-8'); // 开启格式化输出,保留缩进匹配预期格式 $dom->formatOutput = true; $dom->load(__DIR__ . '/Book.xml'); // 定位到Students节点 $studentsNode = $dom->getElementsByTagName('Students')->item(0); // 获取Students的下一个兄弟节点,作为插入位置的参考锚点 $refNode = $studentsNode->nextSibling; // 创建文档片段,加载待插入的XML内容 $fragment = $dom->createDocumentFragment(); $fragment->appendXML(file_get_contents(__DIR__ . '/edit.xml')); // 在School根节点上执行插入,把新片段放到Grade节点之前 $studentsNode->parentNode->insertBefore($fragment, $refNode); // 保存结果文件 $dom->save('output.xml');
提示:如果待插入的XML包含复杂命名空间、特殊字符,建议单独实例化DOMDocument加载
edit.xml,再通过importNode()方法将节点导入主文档后插入,避免XML解析报错。
内容的提问来源于stack exchange,提问作者M.Saeed
相关产品推荐
相关产品推荐

