SimpleXML how to prepend a child in a node?

2019-01-09 10:38发布

When I call

addChild('actor', 'John Doe');

this child is added in the last. Is there a way to make this new child a first child?

标签: php simplexml
3条回答
Fickle 薄情
2楼-- · 2019-01-09 11:03

It doesn't look like SimpleXML supports doing that, so you have two options:

  1. Use the DOM module instead (or one of the other XML modules, probably), and use the DOMNode::insertBefore method, or

  2. Create a new SimpleXMLElement, copy over the attributes, then add your new node, then add all the children of your original node after that, then replace the original with the new one.

update: After a bit more looking through the docs, I'd suggest something like the following (assuming you still want to stick with SimpleXML for the most part, otherwise, just use DOM directly for everything):

$dom_elem = dom_import_simplexml($simple_xml_element);
$dom_elem->insertBefore(dom_import_simplexml($new_element), $dom_elem->firstChild);
查看更多
乱世女痞
3楼-- · 2019-01-09 11:09

As it's been mentionned, SimpleXML doesn't support that so you'd have to use DOM. Here's what I recommend: extend SimpleXMLElement with whatever you need to use in your programs. This way, you can keep all the DOM manipulation and other XML magic outside of your actual program. By keeping the two matters separate, you improve readability and maintainability.

Here's how to extend SimpleXMLElement with a new method prependChild():

class my_node extends SimpleXMLElement
{
    public function prependChild($name, $value)
    {
        $dom = dom_import_simplexml($this);

        $new = $dom->insertBefore(
            $dom->ownerDocument->createElement($name, $value),
            $dom->firstChild
        );

        return simplexml_import_dom($new, get_class($this));
    }
}

$actors = simplexml_load_string(
    '<actors>
        <actor>Al Pacino</actor>
        <actor>Zsa Zsa Gabor</actor>
    </actors>',
    'my_node'
);

$actors->addChild('actor', 'John Doe - last');
$actors->prependChild('actor', 'John Doe - first');

die($actors->asXML());
查看更多
beautiful°
4楼-- · 2019-01-09 11:10

Assuming you can use the function insert_before you could use the following function:

function prependChild(parent, node) { parent.insertBefore(node, parent.firstChild); }

Source reference: XML Matters: Beyond the DOM

查看更多
登录 后发表回答