如何将父节点复制到SimpleXml的当前节点

时间:2018-05-15 17:30:02

标签: php simplexml

我想将XML拆分成更小的块以供进一步处理。 为了自我导入,每个块必须包含其范围之外的所有信息。

假设我配置<项目>作为新的,包含全部的根:

<ROOT>
    <SUBROOT>
        <MOVEME>moveme</MOVEME>
        <ITEM>
            <AAA>111</AAA>
        </ITEM>
        <ITEM>
            <AAA>111</AAA>
        </ITEM>
    </SUBROOT>
</ROOT>

应该成为

<NEWROOT>
        <ITEM>
            <MOVEME>moveme</MOVEME>
            <AAA>111</AAA>
        </ITEM>
        <ITEM>
            <MOVEME>moveme</MOVEME>
            <AAA>111</AAA>
        </ITEM>
</NEWROOT>

什么是高性能解决方案? 谢谢!

1 个答案:

答案 0 :(得分:2)

考虑XSLT(兄弟对XPath),这是一种专门用于将XML文件转换为其他XML,HTML甚至txt文件的语言。 PHP可以运行带有php-xsl类的XSLT 1.0脚本(确保在.ini文件中启用它)。

对于中小型XML文件,XSLT是一个高性能选项,因为您甚至可以在应用程序层避免foreach循环和if逻辑并重建树(即importNode) 。具体来说,在XSLT下面解析为 ITEM 级别,并使用XPath ancestor::*映射到父 SUBROOT 所需项目。将脚本调整为实际节点名称。

XSLT (另存为.xsl文件,一个特殊的.xml文件)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/ROOT">   
        <NEWROOT>
            <xsl:apply-templates select="SUBROOT"/>
        </NEWROOT>
    </xsl:template>

    <xsl:template match="SUBROOT">      
        <xsl:apply-templates select="ITEM"/>
    </xsl:template>

    <xsl:template match="ITEM">
        <xsl:copy>
            <xsl:copy-of select="ancestor::SUBROOT/MOVEME" />
            <xsl:copy-of select="*"/>
        </xsl:copy>
    </xsl:template>
</xsl:transform>

<强> PHP

# LOAD XML AND XSL FILES
$xml = new DOMDocument;
$xml->load('/path/to/input.xml');

$xsl = new DOMDocument;
$xsl->load('/path/to/xslt_script.xsl');

// CONFIGURE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// RUN TRANSFORMATION
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);

// OUTPUT NEW XML
echo $newXML;

// SAVE NEW DOM TREE TO FILE
file_put_contents('/path/to/output.xml', $newXML);

XSLT Demo