douxuan4556
2015-11-17 20:13
浏览 43

PHP中的XML克隆节点

I have to clone an XML node and its childs and append it to a new XML in a specifics tag.

Ie:

Source XML:

<root>
  <element>
    <back>
    <item1>ABC</item1>
    <item2>DEF</item2>
    <more>
      <moreitem>GHI</moreitem>
    </more
    </back>
  </element>
</root>

Destination XML:

<root>
  <base1>
    <item1>FOO</item1>
    <item2>BAR</item2>
  <base2>
    **<back>From source XML and all its childs here</back>**
  </base2>
  </base1>
<root>

图片转代码服务由CSDN问答提供 功能建议

我必须克隆XML节点及其子节点,并将其附加到特定标签中的新XML。

源XML:

 &lt; root&gt; 
&lt; element&gt; \  n&lt; back&gt; 
&lt; item1&gt; ABC&lt; / item1&gt; 
&lt; item2&gt; DEF&lt; / item2&gt; 
&lt; more&gt; 
&lt; moreitem&gt; GHI&lt; / moreitem&gt; 
&lt; / more  
&lt; / back&gt; 
&lt; / element&gt; 
&lt; / root&gt; 
   
 
 

目标XML:

 &lt; root&gt; 
&lt; base1&gt; 
&lt; item1&gt; FOO&lt; / item1&gt; 
&lt; item2&gt; BAR&lt; / item2&gt; 
&lt; base2&gt; 
 **&lt; back&gt; 来自源XML及其所有子项&lt; / back&gt; ** 
&lt; / base2&gt; 
&lt; / base1&gt; 
&lt; root&gt; 
   
 
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • duanping5306 2015-11-17 20:29
    已采纳

    DOMXpath::evaluate() allows you to fetch nodes using Xpath expressions. DOMDocument::importNode() duplicates a node and imports a node into a target document. DOMNode::cloneNode() create a duplicate of node to add in the same document. DOMNode::appendChild() allows you to append the imported/cloned node.

    $source = <<<'XML'
    <root>
      <element>
        <back>
        <item1>ABC</item1>
        <item2>DEF</item2>
        <more>
          <moreitem>GHI</moreitem>
        </more>
        </back>
      </element>
    </root>
    XML;
    
    $target = <<<'XML'
    <root>
      <base1>
        <item1>FOO</item1>
        <item2>BAR</item2>
        <base2>
        </base2>
      </base1>
    </root>
    XML;
    
    $sourceDocument = new DOMDocument();
    $sourceDocument->loadXml($source);
    $sourceXpath = new DOMXpath($sourceDocument);
    
    $targetDocument = new DOMDocument();
    $targetDocument->loadXml($target);
    $targetXpath = new DOMXpath($targetDocument);
    
    foreach ($targetXpath->evaluate('/root/base1/base2[1]') as $targetNode) {
      foreach ($sourceXpath->evaluate('/root/element/back') as $backNode) {
        $targetNode->appendChild($targetDocument->importNode($backNode, TRUE));
      }
    }
    
    echo $targetDocument->saveXml();
    

    Output:

    <?xml version="1.0"?>
    <root>
      <base1>
        <item1>FOO</item1>
        <item2>BAR</item2>
        <base2>
          <back>
            <item1>ABC</item1>
            <item2>DEF</item2>
            <more>
              <moreitem>GHI</moreitem>
            </more>
          </back>
        </base2>
      </base1>
    </root>
    
    打赏 评论
  • dthswrp84966 2015-11-17 20:38

    This is an easy way to do this:

    $src = new DOMDocument();
    $dst = new DOMDocument();
    
    $src->loadXML($src_xml);
    $dst->loadXML($dst_xml);
    
    $back = $src->getElementsByTagName('back')->item(0);
    $base = $dst->getElementsByTagName('base2')->item(0);
    
    $base->appendChild( $dst->importNode( $back, true ) );
    echo $dst->saveXML();
    
    打赏 评论
  • dqhdz04240 2015-11-18 04:18

    Of course you can use XSLT, the native programming language to restructure XML documents to any nuanced needs. Specifically here, you require pulling XML content from an external source XML file. And PHP like other general purpose languages (Java, C#, Python, VB) maintain libraries for XSLT processing.

    XSLT (save as .xsl or .xslt file to be used in PHP below and be sure Source and Destination XML files are in same directory)

    <?xml version="1.0" ?> 
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
     <xsl:output version="1.0" encoding="UTF-8" indent="yes" />
     <xsl:strip-space elements="*" />
    
      <!-- Identity Transform -->
      <xsl:template match="@*|node()">
         <xsl:copy>
           <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
      </xsl:template>
    
      <xsl:template match="back">
       <back>
        <xsl:copy-of select="document('Source.xml')"/>
       </back>
      </xsl:template>
    
    </xsl:transform>
    

    PHP (loading XML and XSL files externally but can be embedded as string)

    $destinationdoc = new DOMDocument();
    $doc1->load('Destination.xml');
    
    $xsl = new DOMDocument;
    $xsl->load('XSLTScript.xsl');
    
    // Configure the transformer
    $proc = new XSLTProcessor;
    $proc->importStyleSheet($xsl); 
    
    // Transform XML source
    $newXml = $proc->transformToXML($doc1);
    
    // Save output to file
    $xmlfile = 'FinalOutput.xml';
    file_put_contents($xmlfile, $newXml);
    

    OUTPUT (using your above posted Source and Destination xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <base1>
        <item1>FOO</item1>
        <item2>BAR</item2>
        <base2>
          <back>
            <root>
              <element>
                <back>
                  <item1>ABC</item1>
                  <item2>DEF</item2>
                  <more>
                    <moreitem>GHI</moreitem>
                  </more>
                </back>
              </element>
            </root>
          </back>
        </base2>
      </base1>
    </root>
    
    打赏 评论

相关推荐 更多相似问题