假设我有一个XML:
<root>
<nodeA />
<nodeA />
<nodeA />
<nodeC />
<nodeC />
<nodeC />
</root>
我该如何在As和Cs之间插入"nodeB"呢?最好用PHP的SimpleXML方式实现。像这样:
<root>
<nodeA />
<nodeA />
<nodeA />
<nodeB />
<nodeC />
<nodeC />
<nodeC />
</root>
假设我有一个XML:
<root>
<nodeA />
<nodeA />
<nodeA />
<nodeC />
<nodeC />
<nodeC />
</root>
我该如何在As和Cs之间插入"nodeB"呢?最好用PHP的SimpleXML方式实现。像这样:
<root>
<nodeA />
<nodeA />
<nodeA />
<nodeB />
<nodeC />
<nodeC />
<nodeC />
</root>
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方法,因此我寻求一种使插入子元素作为第一个子元素更加透明的解决方案。解决方案是将基于DOM的功能隐藏在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;
}
}
$xml = simplexml_load_file($inputFile, 'SimpleXMLElementEx');
现在您可以在任何元素上调用insertChildFirst来将新子元素插入为第一个子元素。该方法返回一个SimpleXML元素作为新元素,因此其用法类似于addChild。当然,很容易创建一个insertChild方法,允许在插入项目之前指定精确的元素,但由于我现在不需要,所以我决定不这样做。