2013-07-15 31 views
5

ho il seguente codice XML (string1):Come sostituire nodo XML con SimpleXMLElement PHP

<?xml version="1.0"?> 
<root> 
    <map> 
     <operationallayers> 
     <layer label="Security" type="feature" visible="false" useproxy="true" usePopUp="all" url="http://stackoverflow.com"/> 
     </operationallayers> 
    </map> 
</root> 

E ho questo pezzo di XML (string2):

<operationallayers> 
    <layer label="Teste1" type="feature" visible="false" useproxy="true" usePopUp="all" url="http://stackoverflow.com"/> 
    <layer label="Teste2" type="dynamic" visible="false" useproxy="true" usePopUp="all" url="http://google.com"/> 
</operationallayers> 

ho usato il funcion simplexml_load_string importare sia alla respectives var:

$xml1 = simplexml_load_string($string1); 
$xml2 = simplexml_load_string($string2); 

Ora, voglio sostituire il 'operationallayers' nodo del stringa1 per il nodo 'operationallayers' della stringa2, ma come?

La classe SimpleXMLElement non ha un metodo 'replaceChild' come il DOM.

risposta

6

Simile a quello che è stato delineato nel SimpleXML: append one tree to another è possibile importare i nodi in DOMDocument perché come si scrive:

"dont La SimpleXMLElement classe ha un metodo 'replaceChild' come il DOM."

Così, quando si importano in DOM è possibile utilizzare quelli:

$xml1 = simplexml_load_string($string1); 
$xml2 = simplexml_load_string($string2); 

$domToChange = dom_import_simplexml($xml1->map->operationallayers); 
$domReplace = dom_import_simplexml($xml2); 
$nodeImport = $domToChange->ownerDocument->importNode($domReplace, TRUE); 
$domToChange->parentNode->replaceChild($nodeImport, $domToChange); 

echo $xml1->asXML(); 

che vi dà il seguente output (non abbelliti):

<?xml version="1.0"?> 
<root> 
    <map> 
     <operationallayers> 
    <layer label="Teste1" type="feature" visible="false" useproxy="true" usePopUp="all" url="http://stackoverflow.com"/> 
    <layer label="Teste2" type="dynamic" visible="false" useproxy="true" usePopUp="all" url="http://google.com"/> 
</operationallayers> 
    </map> 
</root> 

Inoltre è possibile poi prendere questo e aggiungi l'operazione al tuo SimpleXMLElement in modo che sia facilmente incartata. Questo funziona estendendo da SimpleXMLElement:

/** 
* Class MySimpleXMLElement 
*/ 
class MySimpleXMLElement extends SimpleXMLElement 
{ 
    /** 
    * @param SimpleXMLElement $element 
    */ 
    public function replace(SimpleXMLElement $element) { 
     $dom  = dom_import_simplexml($this); 
     $import = $dom->ownerDocument->importNode(
      dom_import_simplexml($element), 
      TRUE 
     ); 
     $dom->parentNode->replaceChild($import, $dom); 
    } 
} 

Utilizzo Esempio:

$xml1 = simplexml_load_string($string1, 'MySimpleXMLElement'); 
$xml2 = simplexml_load_string($string2); 

$xml1->map->operationallayers->replace($xml2); 

correlate: In SimpleXML, how can I add an existing SimpleXMLElement as a child element?.

L'ultima volta che ho esteso SimpleXMLElement su Stackoverflow era in un answer to the "Read and take value of XML attributes" question.

+0

@hakre È possibile farlo funzionare con namespace? – Nightwolf

+0

@hakre Ho creato un wrapper namespace per il mio caso d'uso specifico su $ xml2 ma sarebbe bello averlo incorporato nella classe, se possibile. – Nightwolf

Problemi correlati