XSL检查并输出具有重复元素值的节点

时间:2015-05-28 13:25:25

标签: xml csv xslt element

我目前正在尝试输出包含具有重复元素值的所有节点的列表。以下是我的源XML和XLS:

源XML

<menu>
    <game name="Alien Ambush (USA)" index="" image="">
        <description>Alien Ambush (USA)</description>
        <cloneof></cloneof>
        <crc>34634E16</crc>
        <manufacturer>Micro Distributors</manufacturer>
        <year>1982</year>
        <genre>Shoot-&apos;Em-Up</genre>
        <rating>Other - NR (Not Rated)</rating>
        <enabled>Yes</enabled>
    </game>
    <game name="Alien Game (USA)" index="" image="">
        <description>Alien Game (USA)</description>
        <cloneof></cloneof>
        <crc>34634E16</crc>
        <manufacturer>-</manufacturer>
        <year>19xx</year>
        <genre>Shoot-&apos;Em-Up</genre>
        <rating>Other - NR (Not Rated)</rating>
        <enabled>Yes</enabled>
    </game>
    <game name="Alien Invasion (USA)" index="" image="">
        <description>Alien Invasion (USA)</description>
        <cloneof></cloneof>
        <crc>20679D78</crc>
        <manufacturer>Programma Software</manufacturer>
        <year>1979</year>
        <genre>Shoot-&apos;Em-Up</genre>
        <rating>Other - NR (Not Rated)</rating>
        <enabled>Yes</enabled>
    </game>
    <game name="Night Survival (USA)" index="" image="">
        <description>Night Survival (USA)</description>
        <cloneof></cloneof>
        <crc>34634E16</crc>
        <manufacturer>-</manufacturer>
        <year>19xx</year>
        <genre>Shoot-&apos;Em-Up</genre>
        <rating>Other - NR (Not Rated)</rating>
        <enabled>Yes</enabled>
    </game>
</menu>

所需输出

Alien Ambush (USA),34634E16
Alien Game (USA),34634E16
Night Survival (USA),34634E16

我目前正在使用以下XLS,但它会省略具有重复值的最终节点。

当前XLS

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

    <xsl:template match="game" >
        <xsl:if test="(following::game[crc=current()/crc])">
            <xsl:value-of select="@name"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="crc"/>
            <xsl:text>&#xa;</xsl:text>

        </xsl:if>  
    </xsl:template>   

</xsl:stylesheet> 

当前输出

Alien Ambush (USA),34634E16
Alien Game (USA),34634E16

请注意,我实际上使用的是逗号,因为我将其作为csv提供给Excel,以根据CRC值进行排序。如果我还可以使用XLS对密钥进行排序,那将会很棒。我也尝试输出到以下内容并应用以下XLS按crc排序,但结果保持不变。

输出

<game name="Alien Ambush (USA)">
    <crc>34634E16</crc>
</game>
<game name="Alien Game (USA)">
    <crc>34634E16</crc>
</game>

按CRC排序XLS

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>



    <xsl:template match="game" >
        <xsl:apply-templates>
            <xsl:sort select="crc"/>
        </xsl:apply-templates>
        <xsl:text>&#xa;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

如果有人能给我一些指针会很有帮助。我还是XLS的新手。

1 个答案:

答案 0 :(得分:1)

怎么样:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/menu">
        <xsl:for-each-group select="game" group-by="crc">
            <xsl:sort select="crc" data-type="text" order="ascending"/>
            <xsl:if test="count(current-group()) > 1">
                <xsl:apply-templates select="current-group()"/>
            </xsl:if>
        </xsl:for-each-group>
</xsl:template>

<xsl:template match="game">
    <xsl:value-of select="@name"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select="crc"/>
    <xsl:text>&#10;</xsl:text>
</xsl:template>

</xsl:stylesheet>