Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace XML node with SimpleXMLElement PHP

Tags:

php

xml

simplexml

I have the following XML (string1):

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

And I have this piece of 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>

I used the funcion simplexml_load_string to import both to the respectives var:

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

Now, I want to replace the node 'operationallayers' of the string1 for the node 'operationallayers' of the string2, but how?

The class SimpleXMLElement does not have a method 'replaceChild' like the DOM has.

like image 600
Marcelo Rodovalho Avatar asked Jul 15 '13 18:07

Marcelo Rodovalho


People also ask

How we can change a value of XML document with SimpleXML?

The way to change the value of an attribute, is to change its text value. This can be done using the setAttribute() method or setting the nodeValue property of the attribute node.

How to update XML file using PHP?

php $xml = new DOMDocument('1.0', 'utf-8'); $xml->formatOutput = true; $xml->preserveWhiteSpace = false; $xml->load('examples.

What is SimpleXML extension?

SimpleXML is an extension that allows us to easily manipulate and get XML data. SimpleXML provides an easy way of getting an element's name, attributes and textual content if you know the XML document's structure or layout.


1 Answers

Similar to what has been outlined in SimpleXML: append one tree to another you can import those nodes into DOMDocument because as you write:

"The class SimpleXMLElement dont have a method 'replaceChild' like the DOM."

So when you import into DOM you can use those:

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

Which gives you the following output (non-beautified):

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

Additionally you can then take this and add the operation to your SimpleXMLElement so that it's easily wrapped. This works by extending from 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);
    }
}

Usage Example:

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

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

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

Last time I extended SimpleXMLElement on Stackoverflow was in an answer to the "Read and take value of XML attributes" question.

like image 63
hakre Avatar answered Sep 21 '22 06:09

hakre