排序 xslt 模板样式问题
我正在尝试设置一些 xml 的样式:
<campers>
<camper>
<firstname>James</firstname>
<lastname>West</lastname>
<gender>Boy</gender>
</camper>
<camper>
<firstname>Adam</firstname>
<lastname>West</lastname>
<gender>Boy</gender>
</camper>
<camper>
<firstname>Ann</firstname>
<lastname>Landers</lastname>
<gender>Girl</gender>
</camper>
<camper>
<firstname>Billy</firstname>
<lastname>Batson</lastname>
<gender>Boy</gender>
</camper>
<camper>
<firstname>Diana</firstname>
<lastname>Prince</lastname>
<gender>Girl</gender>
</camper>
</campers>
我想让它们按性别然后按名称排序,但我也想按性别设置标题。我似乎无法让它发挥作用。我的输出应如下所示:
Campers
Boys
Batson, Billy
韦斯特,亚当
詹姆斯·韦斯特
安·女孩
·兰德斯
Prince, Diana
使用以下 xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" version="1.0"/>
<xsl:template match="/">
<html>
<head><title>Camper list</title></head>
<body style="font-family:Arial,Helvetica,sans-serif;font-size:8pt;">
<h2>Campers</h2>
<xsl:apply-templates select="//camper">
<xsl:sort select="gender" />
<xsl:sort select="lastname" />
<xsl:sort select="firstname" />
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="camper">
<xsl:if test="not(gender = preceding::gender)">
<h3><xsl:value-of select="gender"/>s</h3>
</xsl:if>
<xsl:value-of select="lastname"/><xsl:text>, </xsl:text><xsl:value-of select="firstname"/><br />
</xsl:template>
</xsl:stylesheet>
不幸的是,我的输出如下所示:
Campers
Batson, Billy
亚当·韦斯特
男孩
詹姆斯·韦斯特
女孩
安·兰德斯
王子,戴安娜
我确信我在排序上做错了什么,或者排序没有按照我的预期使用。任何建议都会有所帮助。
谢谢,
大卫
附录:基于 lwburk 的解决方案,这就是我想到的:
<xsl:key name="campers-by-gender" match="camper" use="gender" />
<xsl:template match="/">
<html>
<head><title>Camper xsl test</title></head>
<body style="font-family:Arial,Helvetica,sans-serif;font-size:8pt;">
<h2>Campers</h2>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="campers">
<xsl:for-each select="camper[count(. | key('campers-by-gender', gender)[1]) = 1]">
<h3><xsl:value-of select="key('campers-by-gender', gender)/gender"/>s</h3>
<xsl:for-each select="key('campers-by-gender', gender)">
<xsl:sort select="lastname" />
<xsl:sort select="firstname" />
<xsl:value-of select="lastname"/><xsl:text>, </xsl:text><xsl:value-of select="firstname"/><br />
</xsl:for-each>
</xsl:for-each>
</xsl:template>
感谢所有的帮助和好主意! D .
I am trying to style some xml:
<campers>
<camper>
<firstname>James</firstname>
<lastname>West</lastname>
<gender>Boy</gender>
</camper>
<camper>
<firstname>Adam</firstname>
<lastname>West</lastname>
<gender>Boy</gender>
</camper>
<camper>
<firstname>Ann</firstname>
<lastname>Landers</lastname>
<gender>Girl</gender>
</camper>
<camper>
<firstname>Billy</firstname>
<lastname>Batson</lastname>
<gender>Boy</gender>
</camper>
<camper>
<firstname>Diana</firstname>
<lastname>Prince</lastname>
<gender>Girl</gender>
</camper>
</campers>
I want to have them sorted by gender then name, but I also want to have a header by gender. I cannot seem to get this to work. My output should look like this:
Campers
Boys
Batson, Billy
West, Adam
West, James
Girls
Landers, Ann
Prince, Diana
Using the following xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" version="1.0"/>
<xsl:template match="/">
<html>
<head><title>Camper list</title></head>
<body style="font-family:Arial,Helvetica,sans-serif;font-size:8pt;">
<h2>Campers</h2>
<xsl:apply-templates select="//camper">
<xsl:sort select="gender" />
<xsl:sort select="lastname" />
<xsl:sort select="firstname" />
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="camper">
<xsl:if test="not(gender = preceding::gender)">
<h3><xsl:value-of select="gender"/>s</h3>
</xsl:if>
<xsl:value-of select="lastname"/><xsl:text>, </xsl:text><xsl:value-of select="firstname"/><br />
</xsl:template>
</xsl:stylesheet>
Unfortunately, my output looks like this:
Campers
Batson, Billy
West, Adam
Boys
West, James
Girls
Landers, Ann
Prince, Diana
I am sure I am doing something wrong with the sort, or the sort is not being used as I expect it to be. Any suggestions would help.
Thanks,
David
Addendum: Based on lwburk's solution, here is what I came up with:
<xsl:key name="campers-by-gender" match="camper" use="gender" />
<xsl:template match="/">
<html>
<head><title>Camper xsl test</title></head>
<body style="font-family:Arial,Helvetica,sans-serif;font-size:8pt;">
<h2>Campers</h2>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="campers">
<xsl:for-each select="camper[count(. | key('campers-by-gender', gender)[1]) = 1]">
<h3><xsl:value-of select="key('campers-by-gender', gender)/gender"/>s</h3>
<xsl:for-each select="key('campers-by-gender', gender)">
<xsl:sort select="lastname" />
<xsl:sort select="firstname" />
<xsl:value-of select="lastname"/><xsl:text>, </xsl:text><xsl:value-of select="firstname"/><br />
</xsl:for-each>
</xsl:for-each>
</xsl:template>
Thanks for all the help and good ideas!
D.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要先分组然后排序:
这会在源文档上产生以下输出:
You need to group first and then sort:
Which produces the following output on your source document:
我确信还有几种更简单的方法可以做到这一点!
im sure there are several more simple ways to do this!