SimpleXML, как добавить ребенка в узел? - PullRequest
10 голосов
/ 19 января 2010

Когда я звоню

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

этот ребенок добавлен в последний. Есть ли способ сделать этого нового ребенка первым ребенком?

Ответы [ 3 ]

21 голосов
/ 19 января 2010

Как уже упоминалось, SimpleXML не поддерживает это, поэтому вам придется использовать DOM. Вот что я рекомендую: расширьте SimpleXMLElement всем, что вам нужно использовать в своих программах. Таким образом, вы можете сохранить все манипуляции с DOM и другую магию XML вне вашей реальной программы. Разделяя эти два вопроса, вы улучшаете удобочитаемость и удобство обслуживания.

Вот как расширить SimpleXMLElement с помощью нового метода 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());
5 голосов
/ 19 января 2010

Не похоже, что SimpleXML поддерживает это, поэтому у вас есть два варианта:

  1. Вместо этого используйте модуль DOM (или, возможно, один из других модулей XML) и используйте метод DOMNode :: insertBefore или

  2. Создайте новый SimpleXMLElement, скопируйте атрибуты, затем добавьте ваш новый узел, затем добавьте все дочерние элементы вашего исходного узла, а затем замените оригинал на новый.

Обновление: Еще немного посмотрев документы, я бы предложил что-то вроде следующего (при условии, что вы все еще хотите придерживаться SimpleXML, в противном случае, просто используйте DOM напрямую для всего):

$dom_elem = dom_import_simplexml($simple_xml_element);
$dom_elem->insertBefore(dom_import_simplexml($new_element), $dom_elem->firstChild);
2 голосов
/ 19 января 2010

Предполагая, что вы можете использовать функцию insert_before, вы можете использовать следующую функцию:

функция prependChild (родитель, узел) { parent.insertBefore (node, parent.firstChild); }

Ссылка на источник: Вопросы XML: за пределами DOM

...