【问题标题】:How to replace XML node with SimpleXMLElement PHP如何用 SimpleXMLElement PHP 替换 XML 节点
【发布时间】:2013-07-13 17:26:00
【问题描述】:

我有以下 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>

我有这段 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>

我使用函数 simplexml_load_string 将两者都导入到各自的 var:

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

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

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

【问题讨论】:

    标签: php xml simplexml


    【解决方案1】:

    类似于SimpleXML: append one tree to another 中概述的内容,您可以将这些节点导入DOMDocument,因为在您编写时:

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

    因此,当您导入 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();
    

    这会给你以下输出(非美化):

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

    此外,您可以使用它并将操作添加到您的 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);
        }
    }
    

    用法示例:

    $xml1 = simplexml_load_string($string1, 'MySimpleXMLElement');
    $xml2 = simplexml_load_string($string2);
    
    $xml1->map->operationallayers->replace($xml2);
    

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

    上次我在 Stackoverflow 上扩展 SimpleXMLElement 是在 answer to the "Read and take value of XML attributes" question 中。

    【讨论】:

    • @hakre 是否可以使用命名空间进行这项工作?
    • @hakre 我在 $xml2 上为我的特定用例创建了一个命名空间包装器,但如果可能的话,最好将它内置到类中。
    猜你喜欢
    • 2015-11-11
    • 2013-07-11
    • 2013-11-05
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    相关资源
    最近更新 更多