我有一个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现在正是我想要的。
我原来的问题没有什么,但我想补充的是修订号。当我找到它时,我会添加它。
答案 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
saxon9he.jar
:包含在Saxon HE中,从http://saxon.sourceforge.net/下载,详细用法在http://saxon.sourceforge.net/saxon7.7/using-xsl.html changelog.xml
:使用svn log --xml
changelogbyauthor.xsl
:上述XSLT 2.0文件tidy
:这是HTML Tidy,可以通过适当的缩进和内容获得更清晰的HTML。