使用 XSLT 进行分组和计数

  • 本文关键字:XSLT 使用 xslt-1.0
  • 更新时间 :
  • 英文 :


我正在尝试使用 XSLT 1.0 评估、分组和计数节点,可能需要一点帮助。 我需要做的是评估一个节点集并创建字符串,然后在输出任何内容之前对其进行分组和计数。

这是我的 XML

<?xml version="1.0" encoding="UTF-8"?>
<DATA>
    <WIDGETS>
        <ITEM>
            <CODE>FX1</CODE>
        </ITEM>
        <ITEM>
            <CODE>SP2</CODE>
        </ITEM>
        <ITEM>
            <CODE>FX1</CODE>
        </ITEM>
        <ITEM>
            <CODE>P4</CODE>
        </ITEM>
        <ITEM>
            <CODE>WT</CODE>
        </ITEM>
        <ITEM>
            <CODE>XQ</CODE>
        </ITEM>
    </WIDGETS>
</DATA>

还有我的样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes" />      
<xsl:template match="DATA/WIDGETS">     
    <xsl:for-each select="ITEM">
        <xsl:choose> 
            <xsl:when test="CODE = 'FX1'">Performance Series </xsl:when>
            <xsl:when test="CODE = 'XQ'">Performance Series </xsl:when>
            <xsl:when test="CODE = 'SP2'">Sports Series </xsl:when>
            <xsl:when test="CODE = 'P4'">Sports Series </xsl:when>
            <xsl:when test="CODE = 'WT'">Classic Series </xsl:when>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>     
</xsl:stylesheet>

电流输出如下所示

Performance Series Sports Series Performance Series Sports Series Classic Series Performance Series

我想要的tp生产是这个

Performance Series(x3) Sports Series(x2) Classic Series

谁能帮忙?

一种方法是将第一个转换(其中将所有 CODE 转换为各自的序列(存储在变量中,然后再次处理变量以计算重复序列:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0">
    <xsl:output method="html" indent="yes" />
    <!-- key declaration to select NEWCODE using its value -->
    <xsl:key name="item" match="NEWCODE" use="."/>
    <xsl:template match="DATA/WIDGETS">
        <!-- variable TEMP, a temporary document containing NEWCODE 
            for every ITEM with respective series as its value -->
        <xsl:variable name="TEMP">
            <xsl:for-each select="ITEM">
                <NEWCODE>
                    <xsl:choose>
                        <xsl:when test="CODE = 'FX1'">Performance Series </xsl:when>
                        <xsl:when test="CODE = 'XQ'">Performance Series </xsl:when>
                        <xsl:when test="CODE = 'SP2'">Sports Series </xsl:when>
                        <xsl:when test="CODE = 'P4'">Sports Series </xsl:when>
                        <xsl:when test="CODE = 'WT'">Classic Series </xsl:when>
                    </xsl:choose>
                </NEWCODE>
            </xsl:for-each>
        </xsl:variable>
        <!-- iterating on every first NEWCODE(of its series) in variable TEMP, 
             and creating the desired string with count of its series --> 
        <xsl:for-each select="exslt:node-set($TEMP)/NEWCODE[count(. | key('item', .)[1]) = 1]">
            <xsl:value-of select="concat(., '(x', count(key('item', .)),') ')"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

变量 TEMP 的处理是使用 Muenchian 的分组完成的,该分组使用 key() 对元素进行分组。

在此答案中,在文档顶部声明了一个xsl:key,稍后在xsl:for-each中使用该按其值选择NEWCODE

xsl:for-each迭代NEWCODE的第一次出现(首先是它们的值(以 $TEMP 为单位(。在 xsl:for-each 中,count(key('item', .))将计算所有值与您正在迭代的当前NEWCODE相同的NEWCODE

或者,您可以通过匹配每个类的第一项并将其转换以提供该类的项的总数来执行此操作:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes" />
<xsl:template match="DATA/WIDGETS">     
  <xsl:apply-templates select="ITEM" />
</xsl:template>
<xsl:template match="ITEM"/>
<xsl:template match="ITEM[CODE = 'FX1' or CODE = 'XQ'][1]">
  <xsl:variable name="count" select="count(following-sibling::ITEM[CODE = 'FX1' or CODE = 'XQ']) + 1"/>
  <xsl:text>Performance Series</xsl:text>
  <xsl:if test="$count > 1">(x<xsl:value-of select="$count"/>)</xsl:if>
  <xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="ITEM[CODE = 'SP2' or CODE = 'P4'][1]">
  <xsl:variable name="count" select="count(following-sibling::ITEM[CODE = 'SP2' or CODE = 'P4']) + 1"/>
  <xsl:text>Sports Series</xsl:text>
  <xsl:if test="$count > 1">(x<xsl:value-of select="$count"/>)</xsl:if>
  <xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="ITEM[CODE = 'WT'][1]">
  <xsl:variable name="count" select="count(following-sibling::ITEM[CODE = 'WT']) + 1"/>
  <xsl:text>Classic Series</xsl:text>
  <xsl:if test="$count > 1">(x<xsl:value-of select="$count"/>)</xsl:if>
  <xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>

这确实存在某些选择器重复部分的影响,但对我来说,它比其他答案更惯用。 它还避免了依赖扩展函数,无论支持多么广泛。扬子晚报.

相关内容

  • 没有找到相关文章

最新更新