2010-01-19 10 views

risposta

20

Come è stata menzionata, SimpleXML non supporta che così avresti dovuto usare DOM. Ecco cosa consiglio: estendi SimpleXMLElement con tutto ciò che devi usare nei tuoi programmi. In questo modo, puoi mantenere tutta la manipolazione del DOM e altra magia XML al di fuori del tuo programma attuale. Tenendo separate le due questioni, si migliora la leggibilità e la manutenibilità.

Ecco come estendere SimpleXMLElement con un nuovo metodo 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

risposta eccellente. – understack

+0

Esattamente quello che stavo cercando - grazie –

+0

Chiamata al metodo non definito SimpleXMLElement :: prependChild() – user254153

5

Non sembrare SimpleXML supporta farlo, in modo da avere due opzioni:

  1. utilizzare il modulo DOM invece (o uno degli altri moduli XML, probabilmente), e utilizzare il DOMNode::insertBefore method, oppure

  2. Creare un nuovo SimpleXMLElement, copiare gli attributi, quindi aggiungere il nuovo nodo, quindi aggiungere tutti i figli del nodo originale, quindi sostituire l'originale con quello nuovo.

aggiornamento: Dopo un po 'più di consultare i documenti, io suggerirei qualcosa come il seguente (supponendo che si vuole ancora di attaccare con SimpleXML per la maggior parte, in caso contrario, basta usare DOM direttamente tutto):

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

sto già usando secondo approccio. Ma sembrava brutto, quindi pensavo di chiedere alternative migliori. – understack

2

Supponendo è possibile utilizzare la funzione di insert_before è possibile utilizzare la seguente funzione:

funzione prependChild (genitore, nodo) { parent.insertBefore (node, parent.firstChild); riferimento }

Fonte: XML Matters: Beyond the DOM

+0

+1 per la definizione della funzione – understack

Problemi correlati