xsl转换按作者分组的svn日志

时间:2014-05-12 12:59:47

标签: xml svn xslt

我有一个xml格式的Subversion更改日志,用

创建
svn log http://svnurl -r {2014-01-01}:{2014-05-01} --xml > changelog.xml

这给了我一个带

的XML文件
<?xml version="1.0" encoding="UTF-8"?>
<log>
<logentry
   revision="1234">
<author>foo</author>
<date>2014-02-14T13:19:30.288981Z</date>
<msg>Commit by foo</msg>
</logentry>
<logentry
   revision="1235">
<author>bar</author>
<date>2014-02-14T13:57:54.506257Z</date>
<msg>Commit1 by bar</msg>
</logentry>
<logentry
   revision="1236">
<author>bar</author>
<date>2014-03-14T13:57:54.506257Z</date>
<msg>Commit2 by bar</msg>
</logentry>
</log>

我想将其转换为HTML文件:

<html>
<body>
<h2>Change log by author</h2>
<ul>
  <li><h3>foo</h3>
    <ul>
      <li>Commit by foo</li>
    </ul>
  </li>
  <li><h3>bar</h3>
    <ul>
      <li>Commit1 by bar</li>
      <li>Commit2 by bar</li>
    </ul>
  </li>
</ul>
</body>
</html>

这是我在经过几个小时的谷歌搜索和堆栈溢出(没有以前的xml知识)后想出来的:

<xsl:stylesheet version="2.0" 
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<html xmlns="http://www.w3.org/1999/xhtml">
    <body>
        <h2>Change log</h2>
        <ul>
            <xsl:template match="/">
                    <xsl:for-each-group select="log/logentry" group-by="author">
                        <li><h3><xsl:value-of select="author"/></h3>
                            <ul>
                                <xsl:for-each select="current-group()">
                                    <li><xsl:value-of select="msg"/></li>
                                </xsl:for-each>
                            </ul>
                        </li>
                    </xsl:for-each-group>
            </xsl:template>
        </ul>
    </body>
</html>
</xsl:stylesheet>

我用XML Notepad测试了这个,但遗憾的是我没有输出。此外,Internet Explorer和Chrome不会转换文件。我在这里失踪的显而易见的是什么?

编辑:我转储 Microsoft XML Notepad 并安装了 Altova Missionkit 的30天评估版。有了这个,并且在关注我在http://www.jenitennison.com/xslt/grouping/muenchian.html找到的 The Muenchian Method 的例子时,我提出了这个:

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

 <xsl:key name="changelog-by-author" match="logentry" use="author" />
 <xsl:template match="log">
    <xsl:for-each select="logentry[count(. | key('changelog-by-author', author)[1]) = 1]">
                <xsl:sort select="author" />
                <h2><xsl:value-of select="author" /></h2>
                <ul>
                    <xsl:for-each select="key('changelog-by-author', author)">
                        <xsl:sort select="msg" />
                        <li><xsl:value-of select="msg" /></li>
                    </xsl:for-each>
                </ul>
            </xsl:for-each>    
 </xsl:template>
</xsl:stylesheet>

生成的HTML现在正是我想要的。

我原来的问题没有什么,但我想补充的是修订号。当我找到它时,我会添加它。

2 个答案:

答案 0 :(得分:1)

由于缺乏对XSLT 2.0的支持,它无法在浏览器中运行。截至此日期,Internet Explorer和Chrome 尚未获得对XSLT 2.0的原生支持。对于它在这些浏览器中的重要性,您必须在XSLT 1.0中使用 Muenchian分组来对日志条目进行分组,因为XSLT 1.0不支持for-each-group

除此之外,您的转换不正确,因为HTML标记位于<xsl:template>之外。如果将它们放在模板中,它将起作用(在XSLT 2.0兼容处理器中):

<xsl:stylesheet version="2.0" ... >
    <xsl:template match="/">
    <html >
        <body> ... </body>
    </html>
    </xsl:template>
</xsl:stylesheet>

进行转换的另一种方法是使用文字结果元素。在这种情况下,您不需要完整的XSLT模板。在文档中使用XSL标记之前,应该放置XSLT命名空间和版本:

<html xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <body>
        <h2>Change log</h2>
        <ul>
            <xsl:for-each-group select="log/logentry" group-by="author">
                <li><h3><xsl:value-of select="author"/></h3>
                    <ul>
                        <xsl:for-each select="current-group()">
                            <li><xsl:value-of select="msg"/></li>
                        </xsl:for-each>
                    </ul>
                </li>
            </xsl:for-each-group>
        </ul>
    </body>
</html>

答案 1 :(得分:0)

我完全抛弃了Windows,现在我正在使用Linux。为了将来参考,我将这个XML文件转换为bash oneliner。我在这里发帖是因为我在StackOverflow上搜索并找不到任何好问题或任何好的答案。

java -jar ~/Downloads/SaxonHE9-5-1-6J/saxon9he.jar \
    changelog.xml changelogbyauthor.xsl | tidy -ic -o changelog.html