每月和每年组合的群体响应

时间:2011-01-09 05:36:27

标签: xslt xslt-1.0 muenchian-grouping

我想编写xslt来获取输入xml的响应。提前致谢。我想对输出进行分组,以便不对每个员工详细信息重复月份组合。

输入XML:

<resultset>
    <row>
        <column>
            <name>Month</name>
            <value>2</value>
        </column>
        <column>
            <name>Year</name>
            <value>2010</value>
        </column>
        <column>
            <name>EmpName</name>
            <value>Anu</value>
        </column>
        <column>
            <name>Age</name>
            <value>24</value>
        </column>
    </row>
    <row>
        <column>
            <name>Month</name>
            <value>2</value>
        </column>
        <column>
            <name>Year</name>
            <value>2010</value>
        </column>
        <column>
            <name>EmpName</name>
            <value>Nancy</value>
        </column>
        <column>
            <name>Age</name>
            <value>26</value>
        </column>
    </row>
    <row>
        <column>
            <name>Month</name>
            <value>3</value>
        </column>
        <column>
            <name>Year</name>
            <value>2010</value>
        </column>
        <column>
            <name>EmpName</name>
            <value>Ned</value>
        </column>
        <column>
            <name>Age</name>
            <value>25</value>
        </column>
    </row>
</resultset>

预期输出:

<Response>
    <PeriodInfo>
        <Month>2</Month>
        <Year>2010</Year>
        <EmployeeDetails>
            <Name>Anu</Name>
            <Age>24</Age>
        </EmployeeDetails>
        <EmployeeDetails>
            <Name>Nancy</Name>
            <Age>26</Age>
        </EmployeeDetails>
    </PeriodInfo>
    <PeriodInfo>
        <Month>3</Month>
        <Year>2010</Year>
        <EmployeeDetails>
            <Name>Ned</Name>
            <Age>25</Age>
        </EmployeeDetails>
    </PeriodInfo>
</Response>

2 个答案:

答案 0 :(得分:2)

定义一个键&#34;逐行&#34;,按年和月对行进行索引。

然后使用Muenchian分组在输入中选择唯一的年 - 月组合。 &#34;行&#34;每个模板都应用一次。

生成&#34; EmployeeDetails&#34;输出,使用key()选择与当前摘要行具有相同年月的所有行。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

    <xsl:key name="row-by-month" match="row" 
             use="concat(column[name='Year']/value,'-',
                         column[name='Month']/value)" />

    <xsl:template match="resultset">
        <Response>
            <xsl:apply-templates 
                 select="row[generate-id(.) =
                             generate-id(key('row-by-month',
                                             concat(column
                                                      [name='Year']
                                                      /value,
                                                    '-',
                                                    column
                                                      [name='Month']
                                                      /value))[1])]"/>
        </Response>
    </xsl:template>

    <xsl:template match="row">
        <PeriodInfo>
            <Year>
                <xsl:value-of select="column[name='Year']/value"/>
            </Year>
            <Month>
                <xsl:value-of select="column[name='Month']/value"/>
            </Month>
            <xsl:apply-templates select="key('row-by-month',
                                             concat(column
                                                      [name='Year']
                                                      /value,
                                                    '-',
                                                    column
                                                      [name='Month']
                                                      /value))"
                                 mode="details"/>
        </PeriodInfo>
    </xsl:template>

    <xsl:template match="row" mode="details">
        <EmployeeeDetails>
            <Name>
                <xsl:value-of select="column[name='EmpName']/value"/>
            </Name>
            <Age>
                <xsl:value-of select="column[name='Age']/value"/>
            </Age>
        </EmployeeeDetails>
    </xsl:template>


</xsl:stylesheet>

答案 1 :(得分:0)

这是@Lachlan-Roche解决方案基本上更具可读性的变体

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

 <xsl:key name="kRowByDate" match="row"
  use="concat(column[name='Year']/value,
             '+',
             column[name='Month']/value)"/>

 <xsl:template match="/*">
  <Response>
    <xsl:apply-templates/>
  </Response>
 </xsl:template>

 <xsl:template match=
  "row[generate-id()
        =
         generate-id(key('kRowByDate',
                         concat(column[name='Year']/value,
                                '+',
                                column[name='Month']/value)
                         )[1]
                     )
         ]
  ">
  <xsl:variable name="vMonth" select="column[name='Month']/value"/>
  <xsl:variable name="vYear" select="column[name='Year']/value"/>
  <PeriodInfo>
    <Month><xsl:value-of select="$vMonth"/></Month>
    <Year><xsl:value-of select="$vYear"/></Year>
    <xsl:apply-templates mode="data"
      select="key('kRowByDate', concat($vYear,'+',$vMonth))"/>
  </PeriodInfo>
 </xsl:template>

 <xsl:template match="row"/>

 <xsl:template match="row" mode="data">
  <EmployeeDetails>
   <Name><xsl:value-of select="column[name='EmpName']/value"/></Name>
   <Age><xsl:value-of select="column[name='Age']/value"/></Age>
  </EmployeeDetails>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档

<resultset>
    <row>
        <column>
            <name>Month</name>
            <value>2</value>
        </column>
        <column>
            <name>Year</name>
            <value>2010</value>
        </column>
        <column>
            <name>EmpName</name>
            <value>Anu</value>
        </column>
        <column>
            <name>Age</name>
            <value>24</value>
        </column>
    </row>
    <row>
        <column>
            <name>Month</name>
            <value>2</value>
        </column>
        <column>
            <name>Year</name>
            <value>2010</value>
        </column>
        <column>
            <name>EmpName</name>
            <value>Nancy</value>
        </column>
        <column>
            <name>Age</name>
            <value>26</value>
        </column>
    </row>
    <row>
        <column>
            <name>Month</name>
            <value>3</value>
        </column>
        <column>
            <name>Year</name>
            <value>2010</value>
        </column>
        <column>
            <name>EmpName</name>
            <value>Ned</value>
        </column>
        <column>
            <name>Age</name>
            <value>25</value>
        </column>
    </row>
</resultset>

产生了想要的正确结果

<Response>
   <PeriodInfo>
      <Month>2</Month>
      <Year>2010</Year>
      <EmployeeDetails>
         <Name>Anu</Name>
         <Age>24</Age>
      </EmployeeDetails>
      <EmployeeDetails>
         <Name>Nancy</Name>
         <Age>26</Age>
      </EmployeeDetails>
   </PeriodInfo>
   <PeriodInfo>
      <Month>3</Month>
      <Year>2010</Year>
      <EmployeeDetails>
         <Name>Ned</Name>
         <Age>25</Age>
      </EmployeeDetails>
   </PeriodInfo>
</Response>