1

尝试学习如何使用 XLS/XLST 将数据导入 Filemaker。我已经掌握了非常基础的知识,但现在我需要优化。

目前,我有大约 11 组数据分裂成兄弟姐妹,我需要在导入过程中将它们组合成一条记录。现在,我使用 11 个单独的 xsl 文件在 11 个单独的导入中导入数据,每个文件专注于一组特定的数据(火灾计数、命中计数、得分等)。这是非常低效的,但我缺乏使用 XLST 更详细地工作并将碎片数据合并到一个记录中的专业知识。

我正在使用的数据示例如下:

<character_list limit="0" returned="2" milliseconds="0">
<character id="5428010618020696081" active_profile_id="15" faction_id="3" head_id="1" title_id="0">
<stats>
<weapon_stat_list>
<weapon_stat item_id="25003" last_save="1354544215" last_save_date="2012-12-03 14:16:55.0" stat_name="weapon_fire_count" value="108" vehicle_id="0"/>
<weapon_stat item_id="25003" last_save="1354544215" last_save_date="2012-12-03 14:16:55.0" stat_name="weapon_hit_count" value="60" vehicle_id="0"/>
<weapon_stat item_id="125" last_save="1354564613" last_save_date="2012-12-03 19:56:53.0" stat_name="weapon_fire_count" value="7708" vehicle_id="0"/>
<weapon_stat item_id="125" last_save="1354564613" last_save_date="2012-12-03 19:56:53.0" stat_name="weapon_play_time" value="13406" vehicle_id="0"/>
<weapon_stat item_id="125" last_save="1354564613" last_save_date="2012-12-03 19:56:53.0" stat_name="weapon_score" value="62012" vehicle_id="0"/>
<weapon_stat item_id="1259" last_save="1354573520" last_save_date="2012-12-03 22:25:20.211913" stat_name="weapon_fire_count" value="22" vehicle_id="0"/>
</weapon_stat_list>
</stats>
</character>
<character id="5428010618040144225" active_profile_id="6" faction_id="2" head_id="1" title_id="80">
<stats>
<weapon_stat_list>
<weapon_stat item_id="126" last_save="1353442416" last_save_date="2012-11-20 20:13:36.0" stat_name="weapon_fire_count" value="130" vehicle_id="0"/>
<weapon_stat item_id="126" last_save="1353442416" last_save_date="2012-11-20 20:13:36.0" stat_name="weapon_play_time" value="336" vehicle_id="0"/>
<weapon_stat item_id="126" last_save="1353442416" last_save_date="2012-11-20 20:13:36.0" stat_name="weapon_score" value="570" vehicle_id="0"/>
<weapon_stat item_id="1260" last_save="1353442416" last_save_date="2012-11-20 20:13:36.099928" stat_name="weapon_fire_count" value="181" vehicle_id="0"/>
<weapon_stat item_id="1260" last_save="1353442416" last_save_date="2012-11-20 20:13:36.100053" stat_name="weapon_play_time" value="471" vehicle_id="0"/>
<weapon_stat item_id="1260" last_save="1353442416" last_save_date="2012-11-20 20:13:36.100189" stat_name="weapon_score" value="635" vehicle_id="0"/>
<weapon_stat item_id="1261" last_save="1353447137" last_save_date="2012-11-20 21:32:17.0" stat_name="weapon_fire_count" value="321" vehicle_id="0"/>
<weapon_stat item_id="1261" last_save="1353447137" last_save_date="2012-11-20 21:32:17.0" stat_name="weapon_play_time" value="442" vehicle_id="0"/>
<weapon_stat item_id="1261" last_save="1353447137" last_save_date="2012-11-20 21:32:17.0" stat_name="weapon_score" value="1228" vehicle_id="0"/>
</weapon_stat_list>
</stats>
</character>
</character_list>

每个角色武器数据记录的唯一标识符将是角色 ID、物品 ID 和车辆 ID 的组合。片段中的数据类型由“stat_name”属性确定。

我需要的输出要点是:

<ROW MODID="1" RECORDID="1" >
    <COL><DATA>5428010618020696081</DATA></COL>
    <COL><DATA>25003</DATA></COL>
    <COL><DATA>0</DATA></COL>
    <COL><DATA>108</DATA></COL>
    <COL><DATA>60</DATA></COL>
    <COL><DATA></DATA></COL>
</ROW>
<ROW MODID="2" RECORDID="2" >
    <COL><DATA>5428010618020696081</DATA></COL>
    <COL><DATA>125</DATA></COL>
    <COL><DATA>0</DATA></COL>
    <COL><DATA>7708</DATA></COL>
    <COL><DATA></DATA></COL>
    <COL><DATA>13406</DATA></COL>
    <COL><DATA>62012</DATA></COL>
</ROW>
<ROW MODID="3" RECORDID="3" >
    <COL><DATA>5428010618020696081</DATA></COL>
    <COL><DATA>1259</DATA></COL>
    <COL><DATA>0</DATA></COL>
    <COL><DATA>22</DATA></COL>
    <COL><DATA></DATA></COL>
    <COL><DATA></DATA></COL>
    <COL><DATA></DATA></COL>
</ROW>
<ROW MODID="4" RECORDID="4" >
    <COL><DATA>5428010618040144225</DATA></COL>
    <COL><DATA>126</DATA></COL>
    <COL><DATA>0</DATA></COL>
    <COL><DATA>130</DATA></COL>
    <COL><DATA></DATA></COL>
    <COL><DATA>336</DATA></COL>
    <COL><DATA>570</DATA></COL>
</ROW>
<ROW MODID="5" RECORDID="5" >
    <COL><DATA>5428010618040144225</DATA></COL>
    <COL><DATA>1260</DATA></COL>
    <COL><DATA>0</DATA></COL>
    <COL><DATA>181</DATA></COL>
    <COL><DATA></DATA></COL>
    <COL><DATA>471</DATA></COL>
    <COL><DATA>635</DATA></COL>
</ROW>
<ROW MODID="6" RECORDID="6" >
    <COL><DATA>5428010618040144225</DATA></COL>
    <COL><DATA>1261</DATA></COL>
    <COL><DATA>0</DATA></COL>
    <COL><DATA>321</DATA></COL>
    <COL><DATA></DATA></COL>
    <COL><DATA>442</DATA></COL>
    <COL><DATA>1228</DATA></COL>
</ROW>

当然还有比这更多的列,但为简单起见将其省略。输出示例具有角色 ID、物品 ID、车辆 ID、开火次数、命中次数、播放时间、得分等“字段”,按各自的顺序排列。

这是我当前用于导入命中计数的 XSL 文件的副本

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://tempuri.org/test.xsd">
        <xsl:template match="/character_list">
                <FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
                        <ERRORCODE>0</ERRORCODE>
                        <PRODUCT BUILD="" NAME="SOE API XML Import" VERSION="2.0" />
                        <DATABASE DATEFORMAT="yyyy.MM.dd" LAYOUT="" NAME="" RECORDS="" TIMEFORMAT="k:mm:ss" />
                        <METADATA>
                                <FIELD EMPTYOK="NO" MAXREPEAT="1" NAME="Character_ID" TYPE="TEXT" />
                                <FIELD EMPTYOK="NO" MAXREPEAT="1" NAME="Item_ID" TYPE="TEXT" />
                                <FIELD EMPTYOK="NO" MAXREPEAT="1" NAME="Vehicle_ID" TYPE="TEXT" />
                                <FIELD EMPTYOK="NO" MAXREPEAT="1" NAME="Value" TYPE="TEXT" />
                        </METADATA>
                        <RESULTSET>
                        <xsl:for-each select="character" >
                                <xsl:variable name="cid">
                                        <xsl:value-of select="@id" />
                                </xsl:variable>
                                <xsl:for-each select="stats/weapon_stat_list/weapon_stat[@stat_name='weapon_hit_count']" >
                                        <xsl:variable name="c">
                                                <xsl:value-of select="position()" />
                                        </xsl:variable>
                                        <ROW MODID="$c" RECORDID="$c" >
                                                <COL><DATA><xsl:value-of select="$cid" /></DATA></COL>
                                                <COL><DATA><xsl:value-of select="@item_id" /></DATA></COL>
                                                <COL><DATA><xsl:value-of select="@vehicle_id" /></DATA></COL>
                                                <COL><DATA><xsl:value-of select="@value" /></DATA></COL>
                                        </ROW>
                                </xsl:for-each>
                        </xsl:for-each>
                        </RESULTSET>
                </FMPXMLRESULT>
    </xsl:template>
</xsl:stylesheet>

在阅读时,似乎我可能需要使用 for-each-group 将信息组合在一起。我将继续尝试并弄清楚我需要做些什么来完成这项工作,但我希望有人可以为我节省一些时间。我也不知道 XLST Filemaker 12 支持什么版本。如果我发现更多,我会保持更新。

4

1 回答 1

0

如果您可以遍历 stat 条目的所有键(根据您的评论,键都是item_id+vehicle_id值对),那么一次聚合属于每个键的所有属性应该很容易。

从您的预期输出看来,对于每个键,只有一个<weapon_stat>带有stat_name='weapon_fire_count'. 鉴于这是正确的,您可以item_id通过迭代这些<weapon_stat>元素轻松获得所有值:

<xsl:for-each select="stats/weapon_stat_list/weapon_stat[@stat_name='weapon_fire_count']" >

从这些元素中,可以直接生成输出字段 Item ID、Vehicle ID 和 Fire Count。对于其他三个字段,您可以使用以下(更高级的)XPath 表达式从适当的同级中选择值:

<xsl:value-of select="../weapon_stat[@stat_name='weapon_hit_count' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" />

诀窍是将各个上下文节点(这些都是兄弟姐妹:)的and与当前节点(即上面选择的节点)的@item_idand进行比较。@vehicle_id../weapon_stat@item_id@vehicle_idfor-each

总而言之,您想用以下内容替换for-eachXSL 文件的内部:

<xsl:for-each select="stats/weapon_stat_list/weapon_stat[@stat_name='weapon_fire_count']" >
    <ROW>
        <COL><DATA><xsl:value-of select="$cid" /></DATA></COL>
        <COL><DATA><xsl:value-of select="@item_id" /></DATA></COL>
        <COL><DATA><xsl:value-of select="@vehicle_id" /></DATA></COL>
        <COL><DATA><xsl:value-of select="@value" /></DATA></COL>
        <COL><DATA><xsl:value-of select="../weapon_stat[@stat_name='weapon_hit_count' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" /></DATA></COL>
        <COL><DATA><xsl:value-of select="../weapon_stat[@stat_name='weapon_play_time' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" /></DATA></COL>
        <COL><DATA><xsl:value-of select="../weapon_stat[@stat_name='weapon_score' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" /></DATA></COL>
    </ROW>
</xsl:for-each>

注意:我省略了MODIDRECORDID计数器,因为没有有效的解决方案可以在此转换中添加它们。但是,获取此转换的结果并通过第二个 XSL 转换添加计数器是很简单的。


更新:在您在评论中给出的pastebin 示例中,似乎并非每个键都有weapon_fire_count统计信息。因此,您需要遍历所有统计信息,而不是仅迭代这些统计条目,如果前面已经存在具有相同键的同级,则省略输出:

<xsl:for-each select="stats/weapon_stat_list/weapon_stat" >
    <xsl:if test="not(boolean(preceding-sibling::weapon_stat[@item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]))">
        <ROW >
            <COL><DATA><xsl:value-of select="$cid" /></DATA></COL>
            <COL><DATA><xsl:value-of select="@item_id" /></DATA></COL>
            <COL><DATA><xsl:value-of select="@vehicle_id" /></DATA></COL>
            <COL><DATA><xsl:value-of select="../weapon_stat[@stat_name='weapon_fire_count' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" /></DATA></COL>
            <COL><DATA><xsl:value-of select="../weapon_stat[@stat_name='weapon_hit_count' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" /></DATA></COL>
            <COL><DATA><xsl:value-of select="../weapon_stat[@stat_name='weapon_play_time' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" /></DATA></COL>
            <COL><DATA><xsl:value-of select="../weapon_stat[@stat_name='weapon_score' and @item_id=current()/@item_id and @vehicle_id=current()/@vehicle_id]/@value" /></DATA></COL>
        </ROW>
    </xsl:if>
</xsl:for-each> 
于 2013-08-15T21:52:14.607 回答