2013-07-15 11 views
5

ich ersetzen haben folgende XML (string1):Wie XML-Knoten mit 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> 

Und ich habe dieses Stück 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> 

ich die funcion verwendet simplexml_load_string sowohl auf die respectives var importieren:

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

Nun möchte ich den Knoten ‚operationallayers‘ des Zeichenfolge1 ersetzen für der Knoten 'operationallayers' der string2, aber wie?

Die Klasse SimpleXMLElement hat keine Methode 'replaceChild' wie das DOM.

Antwort

6

Ähnlich wie in SimpleXML: append one tree to another umrissen wurde, können Sie diese Knoten in DOMDocument importieren können, weil, wie Sie schreiben:

„Die Klasse SimpleXMLElement dont haben eine Methode‚replaceChild‘wie das DOM.“

Also, wenn Sie in DOM importieren können Sie diese verwenden:

$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(); 

Welche Sie die folgende Ausgabe gibt (nicht verschönert):

<?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> 

Zusätzlich können Sie dann nehmen Sie diese und fügen Sie die Operation zu Ihrem SimpleXMLElement hinzu, so dass es leicht verpackt werden kann. Dies funktioniert, indem von SimpleXMLElement erstreckt:

/** 
* 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); 
    } 
} 

Verwendungsbeispiel:

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

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

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

Zuletzt verlängerte ich SimpleXMLElement auf Stackoverflow in einem answer to the "Read and take value of XML attributes" question.

+0

@hakre Ist es möglich, dies mit Namespaces arbeiten zu lassen? – Nightwolf

+0

@hakre Ich habe einen Namespace-Wrapper für meinen speziellen Anwendungsfall auf $ xml2 erstellt, aber es wäre schön, wenn dies in die Klasse eingebaut wäre. – Nightwolf