XML 在 PHP 中克隆节点
XML Clone node in PHP
我必须克隆一个 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>
DOMXpath::evaluate()
允许您使用 Xpath 表达式获取节点。 DOMDocument::importNode()
复制节点并将节点导入目标文档。 DOMNode::cloneNode()
创建节点的副本以添加到同一文档中。 DOMNode::appendChild()
允许您附加 imported/cloned 节点。
$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>
这是一种简单的方法:
$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();
当然,您可以使用本机编程语言 XSLT 来重构 XML 文档以满足任何细微的需求。具体来说,您需要从外部源 XML 文件中提取 XML 内容。 PHP 与其他通用语言(Java、C#、Python、VB)一样,维护用于 XSLT 处理的库。
XSLT (另存为 .xsl 或 .xslt 文件以在下面的 PHP 中使用,并确保源和目标 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);
OUTPUT (使用上面发布的源和目标 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>
我必须克隆一个 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>
DOMXpath::evaluate()
允许您使用 Xpath 表达式获取节点。 DOMDocument::importNode()
复制节点并将节点导入目标文档。 DOMNode::cloneNode()
创建节点的副本以添加到同一文档中。 DOMNode::appendChild()
允许您附加 imported/cloned 节点。
$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>
这是一种简单的方法:
$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();
当然,您可以使用本机编程语言 XSLT 来重构 XML 文档以满足任何细微的需求。具体来说,您需要从外部源 XML 文件中提取 XML 内容。 PHP 与其他通用语言(Java、C#、Python、VB)一样,维护用于 XSLT 处理的库。
XSLT (另存为 .xsl 或 .xslt 文件以在下面的 PHP 中使用,并确保源和目标 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);
OUTPUT (使用上面发布的源和目标 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>