在PHP中合并具有相同属性的XML文件

时间:2012-08-02 06:06:05

标签: php xml merge

我花了最后两个晚上在这里寻找解决方案,但我无法弄清楚这一点。我有多个XML文件,我想循环遍历包含相同属性的节点,并将所有节点合并到输出文件中。这是一个例子:

File1.xml

<game rotnum="241">
  <gamedate> 123 </gamedate>
  <team1> Giants </team1>
  <team2> Eagles </team2>
</game>

File2.xml

<game rotnum="241">
  <line> 4 </line>
  <points> 200 </points>
</game>

Merged.xml

<game rotnum="241">
  <gamedate> 123 </gamedate>
  <team1> Giants </team1>
  <team2> Eagles </team2>
  <line> 4 </line>
  <points> 200 </points>
</game>

或多或少。我需要在PHP中这样做,我认为使用DOM将比XSLT更容易(我不太了解这一点)。

多个文件中有很多节点,我需要根据类似的rotnum属性匹配数据。

我不知道我是否一定需要这样做,但这是我能想到的最简单的方法,可以将我的所有数据放到一个我可以预先通过的simpleXML对象中,并为每个游戏生成单独的表。

这些XML文件来自我使用SimpleXML创建并在本地缓存它们的几个API源。

function stripAndSaveFile($xml) {
    $game = $xml->game;
    $output = new SimpleXMLElement("<justbetlinesfeed></justbetlinesfeed>");
    for ($i = 0; $i < 16; $i++) {
        //Get the date of each game. 
        $spreadpoints = $game[$i]->line->spread->attributes()->points;
        $spreadteam1 = $game[$i]->line->spread->attributes()->team1adj;
        $spreadteam2 = $game[$i]->line->spread->attributes()->team2adj;
        $rotnum = $game[$i]->attributes()->team1rotnum;
        $insert = $output->addChild("game");
        $insert->addAttribute("rotnum", "$rotnum");
        $insert->addChild("spreadpoints", "$spreadpoints");
        $insert->addChild("spreadteam1", "$spreadteam1");
        $insert->addChild("spreadteam2", "$spreadteam2");

    }
    file_put_contents($this->filePath, $output->asXML());
}
}

1 个答案:

答案 0 :(得分:1)

这可能不是你想要的,但也许它会给你一个想法。这需要一个XSLT 2.0处理器,例如Saxon

它正在做的是遍历集合中的所有XML文件(用于测试的本地目录),并通过根元素中的rotnum属性对它们进行分组。它有效地将所有root用户合并到一个文件中。该文件在单独的目录中创建,名称基于rotnum值。

XSLT的输入是任何XML。我使用样式表本身作为输入。

以下是示例......

“input_dir”目录中的XML文件:

<强> file1.xml

<game rotnum="241">
  <gamedate> 123 </gamedate>
  <team1> Giants </team1>
  <team2> Eagles </team2>
</game>

<强> file2.xml

<game rotnum="241">
  <line> 4 </line>
  <points> 200 </points>
</game>

XSLT 2.0(使用Saxon-HE 9.4测试)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vCollection" select="collection('file:///C:/some_absolute_uri/input_dir?input=*.xml')"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/">
        <xsl:for-each-group select="$vCollection/*" group-by="@rotnum">
            <xsl:result-document href="file:///C:/some_absolute_uri/output_dir/{@rotnum}.xml">
                <xsl:copy>
                    <xsl:apply-templates select="@*"/>
                    <xsl:apply-templates select="$vCollection/*[@rotnum=current-grouping-key()]/*"/>                    
                </xsl:copy>
            </xsl:result-document>
        </xsl:for-each-group>
    </xsl:template>

</xsl:stylesheet>

“output_dir”目录中的XML文件:

<强> 241.xml

<game rotnum="241">
   <gamedate> 123 </gamedate>
   <team1> Giants </team1>
   <team2> Eagles </team2>
   <line> 4 </line>
   <points> 200 </points>
</game>