如何用SimpleXMLElement PHP替换XML节点

时间:2022-10-27 07:24:33

I have the following XML (string1):

我有以下XML(string1):

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

And I have this piece of XML (string2):

我有这段XML(string2):

<operationallayers>
    <layer label="Teste1" type="feature" visible="false" useproxy="true" usePopUp="all" url="http://*.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:

我使用函数simplexml_load_string将两者都导入到各自的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?

现在,我想为string2的节点'operationallayers'替换string1的节点'operationallayers',但是如何?

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

SimpleXMLElement类没有像DOM那样的方法'replaceChild'。

1 个解决方案

#1


6  

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

与SimpleXML中概述的类似:将一个树附加到另一个树,您可以将这些节点导入DOMDocument,因为在您编写时:

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

“类SimpleXMLElement没有类似DOM的方法'replaceChild'。”

So when you import into DOM you can use those:

因此,当您导入DOM时,您可以使用以下内容:

$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://*.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:

此外,您可以将此操作添加到SimpleXMLElement中,以便轻松包装。这通过从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?.

相关:在SimpleXML中,如何将现有的SimpleXMLElement添加为子元素?

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

上次我在*上扩展SimpleXMLElement是对“读取和获取XML属性值”问题的回答。

#1


6  

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

与SimpleXML中概述的类似:将一个树附加到另一个树,您可以将这些节点导入DOMDocument,因为在您编写时:

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

“类SimpleXMLElement没有类似DOM的方法'replaceChild'。”

So when you import into DOM you can use those:

因此,当您导入DOM时,您可以使用以下内容:

$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://*.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:

此外,您可以将此操作添加到SimpleXMLElement中,以便轻松包装。这通过从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?.

相关:在SimpleXML中,如何将现有的SimpleXMLElement添加为子元素?

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

上次我在*上扩展SimpleXMLElement是对“读取和获取XML属性值”问题的回答。