PHP中的XML克隆节点

时间:2015-11-17 20:13:39

标签: php xml clone domdocument

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

即:

源XML:

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

目标XML:

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

3 个答案:

答案 0 :(得分:2)

当然,您可以使用本地编程语言XSLT将XML文档重构为任何细微的需求。具体来说,您需要从外部源XML文件中提取XML内容。和其他通用语言(Java,C#,Python,VB)一样,PHP维护用于XSLT处理的库。

XSLT (另存为以下PHP中使用的.xsl或.xslt文件,并确保源和目标XML文件位于同一目录中)

<?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 (从外部加载XML和XSL文件,但可以作为字符串嵌入)

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

输出 (使用您上面发布的来源和目标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>

答案 1 :(得分:1)

DOMXpath::evaluate()允许您使用Xpath表达式获取节点。 DOMDocument::importNode()复制节点并将节点导入目标文档。 DOMNode::cloneNode()创建要在同一文档中添加的节点副本。 DOMNode::appendChild()允许您附加导入/克隆的节点。

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

输出:

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

答案 2 :(得分:0)

这是一种简单的方法:

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