我花了两个晚上在这里寻找解决方案,但一直没能找到。我有多个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>
合并的.xml
<game rotnum="241">
<gamedate> 123 </gamedate>
<team1> Giants </team1>
<team2> Eagles </team2>
<line> 4 </line>
<points> 200 </points>
</game>
或多或少。我需要在PHP中完成这项工作,并且我认为使用DOM将比XSLT更容易(我对此了解不多)。
多个文件中有很多节点,我需要根据类似的rotnum属性来匹配数据。
我不知道我是否一定需要这样做,但这是我能想到的最简单的方法,可以将所有数据放入一个简单的XML对象中,我可以预先遍历该对象,并为每个游戏生成单独的表。
这些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());
}
}
在这种情况下,我更喜欢使用类似DomDocument 的东西
阅读文档:
$dom = new DomDocument();
$dom->load('filename.xml');
$games = $menu->getElementsByTagName("game");
foreach ($games as $game) {
if($game->hasChildNodes)
{
//Set element
$element->nodeValue;
//Store to array or similar
}
这可能不是你想要的,但也许它会给你一个想法。这需要像Saxon这样的XSLT2.0处理器。
它所做的是遍历集合(用于测试的本地目录)中的所有XML文件,并通过根元素中的rotnum
属性对它们进行分组。它有效地将根目录下的所有子目录合并到一个文件中。该文件在一个单独的目录中创建,名称基于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>
XSLT2.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>