PHP中如何动态将XML节点追加至指定节点内?
如何在PHP中将XML的pullquote节点全部插入到body节点中?
你遇到的问题是因为SimpleXML的addChild()方法并不支持直接传入已有的SimpleXMLElement节点——它需要的是新节点的名称和内容,而不是现成的节点对象。要实现把所有pullquote节点移动到body节点里,用DOMDocument会更方便,因为它提供了完整的节点操作API。
下面是两种可行的解决方案:
方法一:直接使用DOMDocument操作
这种方法全程用DOM API处理,适合节点移动、插入这类复杂操作:
// 加载XML文件,保留格式 $dom = new DOMDocument(); $dom->load("files/test2.xml"); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; // 获取目标body节点 $bodyNode = $dom->getElementsByTagName('body')->item(0); // 获取所有pullquote节点 $pullquoteNodes = $dom->getElementsByTagName('pullquote'); // 注意要反向遍历节点列表——因为移除节点会改变列表的长度,正向遍历会漏掉元素 for ($i = $pullquoteNodes->length - 1; $i >= 0; $i--) { $currentPullquote = $pullquoteNodes->item($i); // 先从原父节点移除这个pullquote $currentPullquote->parentNode->removeChild($currentPullquote); // 如果你想精准插入到注释<!-- insert pullquotes here -->的位置 foreach ($bodyNode->childNodes as $child) { if ($child instanceof DOMComment && trim($child->nodeValue) === 'insert pullquotes here') { $bodyNode->insertBefore($currentPullquote, $child); break; } } // 如果不需要精准位置,直接加到body末尾的话,用下面这行代替上面的循环: // $bodyNode->appendChild($currentPullquote); } // 保存修改后的XML文件 $dom->save("files/test2_modified.xml");
方法二:SimpleXML与DOMDocument配合使用
如果你习惯用SimpleXML读取,也可以把SimpleXML对象转换为DOM对象来完成节点移动:
// 先用SimpleXML加载文件 $xml = simplexml_load_file("files/test2.xml"); $body = $xml->body; // 转换为DOM对象 $domDoc = dom_import_simplexml($xml)->ownerDocument; $domBody = dom_import_simplexml($body); // 获取所有pullquote的DOM节点 $pullquotes = $domDoc->getElementsByTagName('pullquote'); // 同样反向遍历移动节点 for ($i = $pullquotes->length - 1; $i >= 0; $i--) { $pullquote = $pullquotes->item($i); $pullquote->parentNode->removeChild($pullquote); // 这里直接加到body末尾,也可以像方法一那样找注释位置插入 $domBody->appendChild($pullquote); } // 保存修改 $domDoc->save("files/test2_modified.xml");
为什么你的原代码不生效?
原代码中$body->addChild($pull1);的用法错误:addChild()的第一个参数必须是字符串类型的节点名称,而不是SimpleXMLElement对象。如果想用SimpleXML复制节点,你需要手动复制节点的所有属性和子节点,这会比用DOM麻烦很多,所以更推荐上面的DOM方案。
内容的提问来源于stack exchange,提问作者Leoh
相关产品推荐
相关产品推荐

