Как я могу выбрать его позицию на основе его сиблинга при добавлении дочернего узла?
Вот пример:
<?php $_XML = ' <Test> <Menu> <Link href="page1.htm" /> <Link href="page2.htm" /> <Link href="page4.htm" /> </Menu> </Test>'; $_RenderedXML = new SimpleXMLElement($_XML); //Add a new Link node $_NewLink = $_RenderedXML->Menu->addChild("Link"); $_NewLink->addAttribute("href", "page3.htm"); echo $_RenderedXML->asXML(); ?>
Это сделает XML с новым узлом ниже его сиблинга. Я хотел бы указать его позицию.
addChild("Link", 2) //or something.
Я знаю, что ответ Artefacto уже принят, но, похоже, он делает больше работы, чем требуется. Более простая альтернатива, использующая его подпись функции, может выглядеть как функция ниже.
function addchild_at(SimpleXMLElement $sxml, $tagname, $i) { $parent = dom_import_simplexml($sxml); $child = $parent->ownerDocument->createElement($tagname); $target = $parent->getElementsByTagname('*')->item($i); if ($target === NULL) { $parent->appendChild($child); } else { $parent->insertBefore($child, $target); } }
,function addchild_at(SimpleXMLElement $sxml, $tagname, $i) { $parent = dom_import_simplexml($sxml); $child = $parent->ownerDocument->createElement($tagname); $target = $parent->getElementsByTagname('*')->item($i); if ($target === NULL) { $parent->appendChild($child); } else { $parent->insertBefore($child, $target); } }
Вы должны отступить к DOM и использовать dom_import_simplexml
.
$_RenderedXML = new SimpleXMLElement($_XML); //Add a new Link node addchild_at($_RenderedXML->Menu, "Link", 2); $_RenderedXML->Menu->Link[2]->addAttribute("href", "page3.htm"); function addchild_at(SimpleXMLElement $sxml, $tagname, $i) { $elem = dom_import_simplexml($sxml); $new = $elem->ownerDocument->createElement($tagname); $chnodes = array(); foreach ($elem->childNodes as $cn) { $chnodes[] = $cn; } $chnodes = array_filter($chnodes, function (DOMNode $dn) { return $dn->nodeType == XML_ELEMENT_NODE; } ); $chnodes = array_values($chnodes); if ($i < count($chnodes)) $elem->insertBefore($new, $chnodes[$i]); else $elem->appendChild($new); }