PHP - дублирующий узел XML с использованием простого XML - PullRequest
1 голос
/ 01 марта 2010

Мне нужно загрузить источник XML с использованием Simple XML, продублировать существующий узел со всеми его дочерними элементами, а затем настроить атрибут этого нового узла перед рендерингом XML. Любое предложение?

Ответы [ 2 ]

20 голосов
/ 01 марта 2010

SimpleXML не может этого сделать, поэтому вам придется использовать DOM .Хорошей новостью является то, что DOM и SimpleXML - это две стороны одной медали, libxml.Поэтому независимо от того, используете ли вы SimpleXML или DOM, вы работаете с одним и тем же деревом.Вот пример:

$thing = simplexml_load_string(
    '<thing>
        <node n="1"><child/></node>
    </thing>'
);

$dom_thing = dom_import_simplexml($thing);
$dom_node  = dom_import_simplexml($thing->node);
$dom_new   = $dom_thing->appendChild($dom_node->cloneNode(true));

$new_node  = simplexml_import_dom($dom_new);
$new_node['n'] = 2;

echo $thing->asXML();

Если вы много делаете такого рода вещи, вы можете попробовать SimpleDOM , который является расширением SimpleXML и позволяет использовать DOMметоды напрямую, без преобразования из и в объекты DOM.

include 'SimpleDOM.php';
$thing = simpledom_load_string(
    '<thing>
        <node n="1"><child/></node>
    </thing>'
);

$new = $thing->appendChild($thing->node->cloneNode(true));
$new['n'] = 2;

echo $thing->asXML();
3 голосов
/ 11 ноября 2011

С SimpleXML лучший способ, который я нашел, - это обходной путь. Это довольно бобо, но это работает:

// Strip it out so it's not passed by reference
$newNode = new SimpleXMLElement($xml->someNode->asXML());

// Modify your value
$newnode['attribute'] = $attValue;

// Create a dummy placeholder for it wherever you need it
$xml->addChild('replaceMe');

// Do a string replace on the empty fake node
$xml = str_replace('<replaceMe/>',$newNode->asXML(),$xml->asXML());

// Convert back to the object
$xml = new SimpleXMLElement($xml); # leave this out if you want the xml

Поскольку это обходной путь для функции, которой нет в SimpleXML, вам нужно знать, что я ожидаю, что это нарушит любые ссылки на объекты, которые вы определили до этого момента, если таковые имеются.

...