我正在尝试设置一些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>
我希望按性别和名称排序,但我也希望按性别排序。我似乎无法让这个工作。我的输出应该如下所示:
使用以下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>
不幸的是,我的输出看起来像这样:
西,詹姆斯
我确信我在排序方面做错了,或者排序没有像我预期的那样被使用。任何建议都会有所帮助。
谢谢,
大卫
附录:根据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。
答案 0 :(得分:1)
您需要先分组,然后排序:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" version="1.0"/>
<xsl:key name="gender" match="camper" use="gender" />
<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 />
</body>
</html>
</xsl:template>
<xsl:template
match="camper[generate-id()=generate-id(key('gender', gender)[1])]">
<h3><xsl:value-of select="gender" />s</h3>
<xsl:apply-templates select="key('gender', gender)" mode="out">
<xsl:sort select="lastname" />
<xsl:sort select="firstname" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="camper" mode="out">
<xsl:value-of select="lastname" />
<xsl:text>, </xsl:text>
<xsl:value-of select="firstname" />
<br />
</xsl:template>
<xsl:template match="camper" />
</xsl:stylesheet>
在源文档中生成以下输出:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Camper list</title>
</head>
<body style="font-family: Arial,Helvetica,sans-serif; font-size: 8pt;">
<h2>Campers</h2>
<h3>Boys</h3>
Batson, Billy<br />
West, Adam<br />
West, James<br />
<h3>Girls</h3>
Landers, Ann<br />
Prince, Diana<br />
答案 1 :(得分:0)
我确定有几种更简单的方法可以做到这一点!
<?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[gender='Boy']">
<xsl:sort select="lastname" />
<xsl:sort select="firstname" />
</xsl:apply-templates>
<xsl:apply-templates select="//camper[gender='Girl']">
<xsl:sort select="lastname" />
<xsl:sort select="firstname" />
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="camper">
<xsl:if test="position() < 2">
<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>