拥有XML Subversion提交日志:
<?xml version="1.0"?>
<log>
<logentry
revision="1236">
<author>me</author>
<date>2011-11-25T08:28:57.024571Z</date>
<msg>JIRA-5678: commit message</msg>
</logentry>
<logentry
revision="1235">
<author>me</author>
<date>2011-11-25T08:28:47.024571Z</date>
<msg>JIRA-5678 - commit2 message</msg>
</logentry>
<logentry
revision="1234">
<author>me</author>
<date>2011-11-25T08:28:37.024571Z</date>
<msg>JIRA-5678 commit3 message</msg>
</logentry>
</log>
我想生成一个按JIRA编号分组的报告,类似于这个:
<table>
<tr><th>revision</th><th>comment</th></tr>
<tr><td colspan=2>JIRA-5678</td></tr>
<tr><td>r1236</td><td>JIRA-5678: commit message</td></tr>
<tr><td>r1235</td><td>JIRA-5678 - commit2 message</td></tr>
<tr><td>r1234</td><td>JIRA-5678 commit3 message</td></tr>
</table>
提取JIRA编号并将其输出到单独列的转换:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="/">
<table summary="JIRAs">
<tr>
<th>JIRA#</th>
<th>revision</th>
<th>message</th>
</tr>
<xsl:for-each select="log/logentry[starts-with(msg,'JIRA-')]">
<tr>
<td><xsl:value-of select="fn:replace(msg,'^(JIRA-\d+).*$', '$1')" /></td>
<td><xsl:value-of select="@revision" /></td>
<td><xsl:value-of select="msg" /></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
进行这种分组的XSLT代码是什么?
更新: 我最终在XML DOM的顶部编写了一个python脚本。如果需要,请发表评论。
答案 0 :(得分:5)
<强>予。这个XSLT 1.0转换:
<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="kEntryByNum" match="logentry" use="substring-before(msg, ':')"/>
<xsl:template match="/*">
<table>
<tr><th>revision</th><th>comment</th></tr>
<xsl:apply-templates select=
"logentry
[generate-id()
=
generate-id(key('kEntryByNum', substring-before(msg, ':'))[1])
]
"/>
</table>
</xsl:template>
<xsl:template match="logentry">
<tr><td colspan="2"><xsl:value-of select="substring-before(msg, ':')"/></td></tr>
<xsl:for-each select="key('kEntryByNum', substring-before(msg, ':'))">
<tr>
<td><xsl:value-of select="@revision"/></td>
<td><xsl:value-of select="msg"/></td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
应用于以下XML文档:
<log>
<logentry revision="1236">
<author>me</author>
<date>2011-11-25T08:28:57.024571Z</date>
<msg>JIRA-5678: commit message</msg>
</logentry>
<logentry revision="1237">
<author>me</author>
<date>2011-11-25T08:28:57.024571Z</date>
<msg>JIRA-5679: commit message</msg>
</logentry>
<logentry revision="1238">
<author>me</author>
<date>2011-11-25T08:28:57.024571Z</date>
<msg>JIRA-5679: commit message</msg>
</logentry>
<logentry revision="1235">
<author>me</author>
<date>2011-11-25T08:28:47.024571Z</date>
<msg>JIRA-5678: - commit2 message</msg>
</logentry>
<logentry revision="1234">
<author>me</author>
<date>2011-11-25T08:28:37.024571Z</date>
<msg>JIRA-5678: commit3 message</msg>
</logentry>
</log>
生成想要的正确结果:
<table>
<tr>
<th>revision</th>
<th>comment</th>
</tr>
<tr>
<td colspan="2">JIRA-5678</td>
</tr>
<tr>
<td>1236</td>
<td>JIRA-5678: commit message</td>
</tr>
<tr>
<td>1235</td>
<td>JIRA-5678: - commit2 message</td>
</tr>
<tr>
<td>1234</td>
<td>JIRA-5678: commit3 message</td>
</tr>
<tr>
<td colspan="2">JIRA-5679</td>
</tr>
<tr>
<td>1237</td>
<td>JIRA-5679: commit message</td>
</tr>
<tr>
<td>1238</td>
<td>JIRA-5679: commit message</td>
</tr>
</table>
<强> II。 XSLT 2.0解决方案:
<xsl:stylesheet version="2.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="kEntryByNum" match="logentry" use="substring-before(msg, ':')"/>
<xsl:template match="/*">
<table>
<tr><th>revision</th><th>comment</th></tr>
<xsl:for-each-group select="logentry" group-by="substring-before(msg, ':')">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</table>
</xsl:template>
<xsl:template match="logentry">
<tr><td colspan="2"><xsl:value-of select="substring-before(msg, ':')"/></td></tr>
<xsl:for-each select="current-group()">
<tr>
<td><xsl:value-of select="@revision"/></td>
<td><xsl:value-of select="msg"/></td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>