PHP SimpleXML:在某个位置插入节点

说我有XML:

<root> <nodeA /> <nodeA /> <nodeA /> <nodeC /> <nodeC /> <nodeC /> </root> 

如何在As和Cs之间插入“nodeB”? 在PHP中,最好通过SimpleXML? 喜欢:

 <root> <nodeA /> <nodeA /> <nodeA /> <nodeB /> <nodeC /> <nodeC /> <nodeC /> </root> 

以下是在其他SimpleXMLElement之后插入新的SimpleXMLElement的函数。 由于这不是SimpleXML可以直接使用的,所以它使用了一些DOM类/方法来实现这个工作。

 function simplexml_insert_after(SimpleXMLElement $insert, SimpleXMLElement $target) { $target_dom = dom_import_simplexml($target); $insert_dom = $target_dom->ownerDocument->importNode(dom_import_simplexml($insert), true); if ($target_dom->nextSibling) { return $target_dom->parentNode->insertBefore($insert_dom, $target_dom->nextSibling); } else { return $target_dom->parentNode->appendChild($insert_dom); } } 

以及如何使用它的一个例子(具体到你的问题):

 $sxe = new SimpleXMLElement('<root><nodeA/><nodeA/><nodeA/><nodeC/><nodeC/><nodeC/></root>'); // New element to be inserted $insert = new SimpleXMLElement("<nodeB/>"); // Get the last nodeA element $target = current($sxe->xpath('//nodeA[last()]')); // Insert the new element after the last nodeA simplexml_insert_after($insert, $target); // Peek at the new XML echo $sxe->asXML(); 

如果你想/需要解释这是如何工作的(代码非常简单,但可能包括外国概念),请问。

Salathe的答案对我有帮助,但是因为我使用了SimpleXMLElement的addChild方法,所以我寻求一种解决scheme,使插入儿童作为第一个孩子更加透明。 解决scheme是采用基于DOM的function,并将其隐藏在SimpleXMLElement的子类中:

 class SimpleXMLElementEx extends SimpleXMLElement { public function insertChildFirst($name, $value, $namespace) { // Convert ourselves to DOM. $targetDom = dom_import_simplexml($this); // Check for children $hasChildren = $targetDom->hasChildNodes(); // Create the new childnode. $newNode = $this->addChild($name, $value, $namespace); // Put in the first position. if ($hasChildren) { $newNodeDom = $targetDom->ownerDocument->importNode(dom_import_simplexml($newNode), true); $targetDom->insertBefore($newNodeDom, $targetDom->firstChild); } // Return the new node. return $newNode; } } 

毕竟,SimpleXML允许指定使用哪个元素类:

 $xml = simplexml_load_file($inputFile, 'SimpleXMLElementEx'); 

现在,您可以在任何元素上调用insertChildFirst以将新子作为第一个子元素插入。 该方法将新元素作为SimpleXML元素返回,所以它的使用类似于addChild。 当然,创build一个insertChild方法是很容易的,它允许指定一个精确的元素来插入项目,但是因为我现在不需要,所以我决定不这样做。