用于对多层结果进行分组的 xsl 转换
xsl Transformation for Grouping multi layer results
我希望有人能帮助我,因为我一直在努力弄清楚如何将数据集转换为 table 在多个级别分组的结构。第一级是事件日期,第二级是公司名称,最后是用户。
下面是XML.
<xmlData>
<records>
<record>
<userid>1</userid>
<usersname>Jane Doe</usersname>
<companyname>Company A</companyname>
<eventdate>01 FEB 2017</eventdate>
<jeventdate>2457786</jeventdate>
</record>
<record>
<userid>3</userid>
<usersname>Jane Doe</usersname>
<companyname>Company B</companyname>
<eventdate>01 FEB 2017</eventdate>
<jeventdate>2457786</jeventdate>
</record>
<record>
<userid>2</userid>
<usersname>Joe Smith</usersname>
<companyname>Company B</companyname>
<eventdate>01 DEC 2016</eventdate>
<jeventdate>2457724</jeventdate>
</record>
<record>
<userid>2</userid>
<usersname>Joe Smith</usersname>
<companyname>Company B</companyname>
<eventdate>01 JAN 2017</eventdate>
<jeventdate>2457755</jeventdate>
</record>
<record>
<userid>2</userid>
<usersname>Joe Smith</usersname>
<companyname>Company B</companyname>
<eventdate>01 FEB 2017</eventdate>
<jeventdate>2457786</jeventdate>
</record>
</records>
</xmlData>
我试图获得的结果显示在以下简单的 HTML 输出中。
<h1>01 DEC 2016</h1>
<h2>Company B</h2>
<table>
<tr><td>2</td><td>Joe Smith</td></tr>
</table>
<h1>01 JAN 2017</h1>
<h2>Company B</h2>
<table>
<tr><td>2</td><td>Joe Smith</td></tr>
</table>
<h1>01 FEB 2017</h1>
<h2>Company A</h2>
<table>
<tr><td>1</td><td>Jane Doe</td></tr>
</table>
<h2>Company B</h2>
<table>
<tr><td>3</td><td>Dave Dodd</td></tr>
<tr><td>2</td><td>Joe Smith</td></tr>
</table>
我遇到的问题实际上有两个部分。首先是获得三个层次的深度。第二个是获取所有记录,而不仅仅是前几条。
这是我一直在使用的 XSL。
<xsl:key name="monthof" match="record" use="eventdate"/>
<xsl:key name="companyof" match="record" use="concat(eventdate,'|',companyname)"/>
<xsl:key name="userof" match="record" use="concat(eventdate,'|',companyname,'|',usersname)"/>
<xsl:template match="xmlData/records">
<xsl:for-each select="record[key('monthof',eventdate)]">
<xsl:sort select="jeventdate"/>
<xsl:variable name="lstEventDate" select="key('monthof',eventdate)" />
<h2><xsl:value-of select="eventdate"/></h2>
<xsl:for-each select="key('companyof',concat(eventdate,'|',companyname))">
<xsl:sort select="companyname"/>
<h3>
<xsl:value-of select="companyname"/>
</h3>
<table>
<xsl:for-each select="key('userof',concat(eventdate,'|',companyname,'|',usersname))">
<tr>
<td><xsl:value-of select="userid"/></td>
<td><xsl:value-of select="usersname"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
这是我得到的输出。
01 DEC 2016
Company B
2 Jane Doe
01 JAN 2017
Company B
2 Jane Doe
01 FEB 2017
Company A
1 Joe Smith
01 FEB 2017
Company B
1 Joe Smith
Company B
3 Dave Dodd
01 FEB 2017
Company B
1 Joe Smith
Company B
2 Jane Doe
您定义的键很好,但是您需要使用它们,正如评论中已经指出的那样,使用 Muenchian grouping 方法:
<xsl:template match="xmlData/records">
<xsl:for-each select="record[generate-id() = generate-id(key('monthof',eventdate)[1])]">
<xsl:sort select="jeventdate"/>
<h2><xsl:value-of select="eventdate"/></h2>
<xsl:for-each select="key('monthof', eventdate)[generate-id() = generate-id(key('companyof',concat(eventdate,'|',companyname))[1])]">
<xsl:sort select="companyname"/>
<h3>
<xsl:value-of select="companyname"/>
</h3>
<table>
<xsl:for-each select="key('companyof',concat(eventdate,'|',companyname))[generate-id() = generate-id(key('userof',concat(eventdate,'|',companyname,'|',usersname))[1])]">
<tr>
<td><xsl:value-of select="userid"/></td>
<td><xsl:value-of select="usersname"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
您可能想检查一下是否不能迁移到 XSLT 2.0,这样操作起来会容易得多
<xsl:template match="xmlData/records">
<xsl:for-each-group select="record" group-by="eventdate">
<xsl:sort select="jeventdate"/>
<h2><xsl:value-of select="eventdate"/></h2>
<xsl:for-each-group select="current-group()" group-by="companyname">
<xsl:sort select="companyname"/>
<h3>
<xsl:value-of select="companyname"/>
</h3>
<table>
<xsl:for-each-group select="current-group()" group-by="usersname">
<tr>
<td><xsl:value-of select="userid"/></td>
<td><xsl:value-of select="usersname"/></td>
</tr>
</xsl:for-each-group>
</table>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:template>
我希望有人能帮助我,因为我一直在努力弄清楚如何将数据集转换为 table 在多个级别分组的结构。第一级是事件日期,第二级是公司名称,最后是用户。
下面是XML.
<xmlData>
<records>
<record>
<userid>1</userid>
<usersname>Jane Doe</usersname>
<companyname>Company A</companyname>
<eventdate>01 FEB 2017</eventdate>
<jeventdate>2457786</jeventdate>
</record>
<record>
<userid>3</userid>
<usersname>Jane Doe</usersname>
<companyname>Company B</companyname>
<eventdate>01 FEB 2017</eventdate>
<jeventdate>2457786</jeventdate>
</record>
<record>
<userid>2</userid>
<usersname>Joe Smith</usersname>
<companyname>Company B</companyname>
<eventdate>01 DEC 2016</eventdate>
<jeventdate>2457724</jeventdate>
</record>
<record>
<userid>2</userid>
<usersname>Joe Smith</usersname>
<companyname>Company B</companyname>
<eventdate>01 JAN 2017</eventdate>
<jeventdate>2457755</jeventdate>
</record>
<record>
<userid>2</userid>
<usersname>Joe Smith</usersname>
<companyname>Company B</companyname>
<eventdate>01 FEB 2017</eventdate>
<jeventdate>2457786</jeventdate>
</record>
</records>
</xmlData>
我试图获得的结果显示在以下简单的 HTML 输出中。
<h1>01 DEC 2016</h1>
<h2>Company B</h2>
<table>
<tr><td>2</td><td>Joe Smith</td></tr>
</table>
<h1>01 JAN 2017</h1>
<h2>Company B</h2>
<table>
<tr><td>2</td><td>Joe Smith</td></tr>
</table>
<h1>01 FEB 2017</h1>
<h2>Company A</h2>
<table>
<tr><td>1</td><td>Jane Doe</td></tr>
</table>
<h2>Company B</h2>
<table>
<tr><td>3</td><td>Dave Dodd</td></tr>
<tr><td>2</td><td>Joe Smith</td></tr>
</table>
我遇到的问题实际上有两个部分。首先是获得三个层次的深度。第二个是获取所有记录,而不仅仅是前几条。
这是我一直在使用的 XSL。
<xsl:key name="monthof" match="record" use="eventdate"/>
<xsl:key name="companyof" match="record" use="concat(eventdate,'|',companyname)"/>
<xsl:key name="userof" match="record" use="concat(eventdate,'|',companyname,'|',usersname)"/>
<xsl:template match="xmlData/records">
<xsl:for-each select="record[key('monthof',eventdate)]">
<xsl:sort select="jeventdate"/>
<xsl:variable name="lstEventDate" select="key('monthof',eventdate)" />
<h2><xsl:value-of select="eventdate"/></h2>
<xsl:for-each select="key('companyof',concat(eventdate,'|',companyname))">
<xsl:sort select="companyname"/>
<h3>
<xsl:value-of select="companyname"/>
</h3>
<table>
<xsl:for-each select="key('userof',concat(eventdate,'|',companyname,'|',usersname))">
<tr>
<td><xsl:value-of select="userid"/></td>
<td><xsl:value-of select="usersname"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
这是我得到的输出。
01 DEC 2016
Company B
2 Jane Doe
01 JAN 2017
Company B
2 Jane Doe
01 FEB 2017
Company A
1 Joe Smith
01 FEB 2017
Company B
1 Joe Smith
Company B
3 Dave Dodd
01 FEB 2017
Company B
1 Joe Smith
Company B
2 Jane Doe
您定义的键很好,但是您需要使用它们,正如评论中已经指出的那样,使用 Muenchian grouping 方法:
<xsl:template match="xmlData/records">
<xsl:for-each select="record[generate-id() = generate-id(key('monthof',eventdate)[1])]">
<xsl:sort select="jeventdate"/>
<h2><xsl:value-of select="eventdate"/></h2>
<xsl:for-each select="key('monthof', eventdate)[generate-id() = generate-id(key('companyof',concat(eventdate,'|',companyname))[1])]">
<xsl:sort select="companyname"/>
<h3>
<xsl:value-of select="companyname"/>
</h3>
<table>
<xsl:for-each select="key('companyof',concat(eventdate,'|',companyname))[generate-id() = generate-id(key('userof',concat(eventdate,'|',companyname,'|',usersname))[1])]">
<tr>
<td><xsl:value-of select="userid"/></td>
<td><xsl:value-of select="usersname"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
您可能想检查一下是否不能迁移到 XSLT 2.0,这样操作起来会容易得多
<xsl:template match="xmlData/records">
<xsl:for-each-group select="record" group-by="eventdate">
<xsl:sort select="jeventdate"/>
<h2><xsl:value-of select="eventdate"/></h2>
<xsl:for-each-group select="current-group()" group-by="companyname">
<xsl:sort select="companyname"/>
<h3>
<xsl:value-of select="companyname"/>
</h3>
<table>
<xsl:for-each-group select="current-group()" group-by="usersname">
<tr>
<td><xsl:value-of select="userid"/></td>
<td><xsl:value-of select="usersname"/></td>
</tr>
</xsl:for-each-group>
</table>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:template>