2010-01-19 19 views

Odpowiedz

20

jak to wymieniono, SimpleXML nie obsługuje, że tak trzeba by użyć DOM. Oto, co polecam: rozszerz SimpleXMLElement o wszystko, czego potrzebujesz w swoich programach. W ten sposób możesz zachować całą manipulację DOM i magię XML poza swoim faktycznym programem. Zachowując te dwie kwestie osobno, poprawiasz czytelność i łatwość konserwacji.

Oto jak przedłużyć SimpleXMLElement z nową metodę 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()); 
+0

Doskonała odpowiedź. – understack

+0

Dokładnie to, czego szukałem - dziękuję –

+0

Wywołanie niezdefiniowanej metody SimpleXMLElement :: prependChild() – user254153

5

To nie wygląda jak SimpleXML obsługuje to robić, więc masz dwie opcje:

  1. użyć modułu DOM zamiast (lub jeden z pozostałych modułów XML, prawdopodobnie), i używać DOMNode::insertBefore method, lub

  2. Utwórz nową SimpleXMLElement, skopiuj atrybuty, następnie dodaj nowy węzeł, następnie dodaj wszystkie elementy podrzędne oryginalnego węzła, a następnie zamień oryginał na nowy.

zmiana: Po nieco więcej pominie docs, sugeruję coś jak następuje (zakładając, że nadal chcesz trzymać się z SimpleXML w przeważającej części, w przeciwnym razie po prostu użyć bezpośrednio do DOM wszystko):

$dom_elem = dom_import_simplexml($simple_xml_element); 
$dom_elem->insertBefore(dom_import_simplexml($new_element), $dom_elem->firstChild); 
+0

już używam 2nd podejście. Ale wyglądało to brzydko, więc pomyślałem o prośbę o lepsze alternatywy. – understack

2

Zakładając, można użyć funkcji insert_before można użyć następujących funkcji:

funkcji prependChild (nadrzędny, node) { parent.insertBefore (node, parent.firstChild); odniesienie }

Źródło: XML Matters: Beyond the DOM

+0

+1 dla definicji funkcji – understack