更新
我想向提供答案的人道歉,我似乎引起了各种各样的困惑。为了避免使事情进一步复杂化,我删除了以前的代码并添加了新信息。请继续阅读...
我正在使用Umbraco的自定义博客。 Umbraco将XML作为输出吐出,然后使用XSLT读取。
XML的结构如下
这是XML代码,我已经清理了很多代码,使其至少有些可读。
<Blog id="1078" parentID="1049" level="2" writerID="0" creatorID="0" nodeType="1073" template="1089" sortOrder="7" createDate="2010-09-27T14:11:04" updateDate="2010-10-12T16:59:12" nodeName="Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078" isDoc="">
<newPageTitle>The Lorem Ipsum Blog</newPageTitle>
<BlogCentre id="1079" parentID="1078" level="3" writerID="0" creatorID="0" nodeType="1075" template="1076" sortOrder="1" createDate="2010-09-27T14:11:49" updateDate="2010-10-07T14:43:13" nodeName="Blog Centre 1" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079" isDoc="">
<Room id="1081" parentID="1079" level="4" writerID="0" creatorID="0" nodeType="1077" template="0" sortOrder="1" createDate="2010-09-27T14:12:26" updateDate="2010-10-07T14:43:06" nodeName="Room 10" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081" isDoc="">
<BlogPost id="1175" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1192" sortOrder="1" createDate="2010-10-07T14:51:48" updateDate="2010-10-12T21:30:53" nodeName="The first ever Blog post" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1175" isDoc="">
<topicTitle>The first ever blog</topicTitle>
</BlogPost>
<BlogPost id="1180" parentID="1081" level="5" writerID="0" creatorID="3" nodeType="1087" template="1089" sortOrder="2" createDate="2010-10-08T15:52:20" updateDate="2010-10-12T16:57:00" nodeName="asdasd" writerName="Administrator" creatorName="ZX" path="-1,1049,1078,1079,1081,1180" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
<BlogPost id="1181" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="3" createDate="2010-10-08T17:50:19" updateDate="2010-10-12T11:40:37" nodeName="condimentum" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1181" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-09-01T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1194" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="4" createDate="2010-10-12T11:41:50" updateDate="2010-10-12T11:42:37" nodeName="Nam augue" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1194" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-08-05T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1195" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="5" createDate="2010-10-12T11:42:15" updateDate="2010-10-12T11:42:25" nodeName="consequat nunc" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1195" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-08-12T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1196" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="6" createDate="2010-10-12T12:05:57" updateDate="2010-10-12T12:08:40" nodeName="cursus congue" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1196" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2009-10-22T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1197" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="7" createDate="2010-10-12T12:08:54" updateDate="2010-10-12T12:09:24" nodeName="inceptos" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1197" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2009-11-19T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1198" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="8" createDate="2010-10-12T12:09:45" updateDate="2010-10-12T12:10:13" nodeName="inceptos himenaeos" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1198" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2009-12-16T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1199" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="9" createDate="2010-10-12T12:10:29" updateDate="2010-10-12T12:10:56" nodeName="consequat" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1199" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-01-13T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1200" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="10" createDate="2010-10-12T12:11:08" updateDate="2010-10-12T12:11:35" nodeName="himenaeos" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1200" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-02-09T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1201" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="11" createDate="2010-10-12T12:11:45" updateDate="2010-10-12T12:12:35" nodeName="cursus congue" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1201" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-04-22T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1202" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="12" createDate="2010-10-12T12:12:18" updateDate="2010-10-12T12:12:45" nodeName="pharetra" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1202" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-03-09T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1203" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="13" createDate="2010-10-12T12:13:05" updateDate="2010-10-12T12:13:27" nodeName="inceptos himenaeos" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1203" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-05-26T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1204" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="14" createDate="2010-10-12T12:13:36" updateDate="2010-10-12T12:13:56" nodeName="pharetra" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1204" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-06-11T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1205" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="15" createDate="2010-10-12T12:14:06" updateDate="2010-10-12T12:14:41" nodeName="Fusce augue" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1205" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-07-08T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1206" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="16" createDate="2010-10-12T12:14:52" updateDate="2010-10-12T12:15:19" nodeName="pharetra et fermentum" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1206" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-08-09T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1207" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="17" createDate="2010-10-12T12:15:31" updateDate="2010-10-12T12:15:51" nodeName="Fusce augue purus" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1207" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-09-14T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1208" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="18" createDate="2010-10-12T12:16:25" updateDate="2010-10-12T12:16:45" nodeName="Class aptent taciti" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1208" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-06-04T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1209" parentID="1081" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="19" createDate="2010-10-12T12:17:01" updateDate="2010-10-12T12:17:29" nodeName="Class aptent" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081,1209" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-06-21T00:00:00</archiveUnder>
</BlogPost>
</Room>
<Room id="1082" parentID="1079" level="4" writerID="0" creatorID="0" nodeType="1077" template="0" sortOrder="2" createDate="2010-09-27T14:12:33" updateDate="2010-10-07T14:43:09" nodeName="Test Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1082" isDoc="">
<BlogPost id="1182" parentID="1082" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="1" createDate="2010-10-08T17:51:19" updateDate="2010-10-08T17:51:58" nodeName="Test Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1082,1182" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
<Room id="1083" parentID="1079" level="4" writerID="0" creatorID="0" nodeType="1077" template="1089" sortOrder="3" createDate="2010-09-27T14:12:40" updateDate="2010-10-07T14:49:48" nodeName="Test Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1083" isDoc="">
<BlogPost id="1183" parentID="1083" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="1" createDate="2010-10-08T17:52:22" updateDate="2010-10-08T17:52:39" nodeName="Test Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1083,1183" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
</BlogCentre>
<BlogCentre id="1080" parentID="1078" level="3" writerID="0" creatorID="0" nodeType="1075" template="1076" sortOrder="2" createDate="2010-09-27T14:11:55" updateDate="2010-10-07T14:43:23" nodeName="Blog Centre 2" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080" isDoc="">
<Room id="1084" parentID="1080" level="4" writerID="0" creatorID="0" nodeType="1077" template="0" sortOrder="1" createDate="2010-09-27T14:12:45" updateDate="2010-10-07T14:43:17" nodeName="Room 1" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1084" isDoc="">
<BlogPost id="1184" parentID="1084" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="1" createDate="2010-10-08T17:53:05" updateDate="2010-10-08T17:53:29" nodeName="Blog Post 3" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1084,1184" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
<Room id="1085" parentID="1080" level="4" writerID="0" creatorID="0" nodeType="1077" template="0" sortOrder="2" createDate="2010-09-27T14:12:50" updateDate="2010-10-07T14:43:19" nodeName="Room 2" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1085" isDoc="">
<BlogPost id="1185" parentID="1085" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="1" createDate="2010-10-08T17:53:51" updateDate="2010-10-08T17:54:15" nodeName="Blog Post 109" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1085,1185" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
<Room id="1086" parentID="1080" level="4" writerID="0" creatorID="0" nodeType="1077" template="1089" sortOrder="3" createDate="2010-09-27T14:12:55" updateDate="2010-10-07T14:50:39" nodeName="Room 3" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1086" isDoc="">
<BlogPost id="1186" parentID="1086" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="1" createDate="2010-10-08T17:54:28" updateDate="2010-10-08T17:54:51" nodeName="Blog Post 123" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1086,1186" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
</BlogCentre>
</Blog>
在Umbraco XSLT样式表中,有一个参数可以传递给当前页面。
<xsl:param name="currentPage" />
这将始终是父节点<Blog />
,因此我们必须在此处开始表单。
您会注意到<Blog />
和<BlogPost />
之间存在中间节点,但我们希望计算每个<BlogCentre />
和<Room />
中的BlogPost总数。
要做到这一点,我一直在使用
<xsl:for-each select="$currentPage/descendant::BlogPost" />
选择所有博客帖子,无论中心/房间。
现在我的要求是,按月和年对每个博客帖子进行分组(包括每个月的帖子计数)。我要将它们分组的日期是属性createDate
除非 有一个名为<archiveUnder>some-date-here</archiveUnder>
的子节点。进一步解释
更新
我可以通过检查属性是否为空来轻松完成此部分,因此如果需要,解决方案可以省略此部分。
<BlogPost createDate="2010-10-08T17:52:22">
<!-- no archiveUnder -->
</BlogPost>
^ 使用创建日期
<BlogPost createDate="2010-10-08T17:52:22">
<archiveUnder>2010-10-08T17:51:19</archiveUnder>
</BlogPost>
^ 使用archiveUnder
最后,这是预期输出的一个示例。
<ul>
<li>
<h3>2010</h3>
<ul>
<li>September (4)</li>
<li>August (2)</li>
<li>June (5)</li> <!-- No July because there are no posts -->
</ul>
</li>
<li>
<h3>2009</h3>
<ul>
<li>April (4)</li>
<li>March (2)</li>
<li>January (5)</li> <!-- No February because there are no posts -->
</ul>
</li>
</ul>
答案 0 :(得分:3)
此转换(141行但已格式化以便于阅读):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:m="my:months" exclude-result-prefixes="m" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="currentPage" select="/*"/>
<m:months>
<m>January</m>
<m>February</m>
<m>March</m>
<m>April</m>
<m>May</m>
<m>June</m>
<m>July</m>
<m>August</m>
<m>September</m>
<m>October</m>
<m>November</m>
<m>December</m>
</m:months>
<xsl:variable name="vMonthNames" select=
"document('')/*/m:months/*"/>
<xsl:key name="kPostsByYear" match="BlogPost"
use="substring-before(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
'-'
)"/>
<xsl:key name="kPostsByYearMonth" match="BlogPost"
use="substring(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
1,7
)"/>
<xsl:template match="/">
<ul>
<xsl:apply-templates mode="year" select=
"$currentPage/*/*/BlogPost
[generate-id()
=
generate-id(key('kPostsByYear',
substring-before(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
'-'
)
)[1]
)
]
">
<xsl:sort order="descending" select=
"substring-before(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
'-'
)
"/>
</xsl:apply-templates>
</ul>
</xsl:template>
<xsl:template match="BlogPost" mode="year">
<xsl:variable name="vYear" select=
"substring-before(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
'-')
"/>
<xsl:variable name="vyearBlogs"
select="key('kPostsByYear',$vYear)"/>
<li>
<h3><xsl:value-of select="$vYear"/></h3>
<ul>
<xsl:apply-templates mode="month" select=
"$vyearBlogs
[generate-id()
=
generate-id(key('kPostsByYearMonth',
substring(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
1,7
)
)[1]
)
]
">
<xsl:sort order="descending" select=
"substring(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
6,2)"
/>
</xsl:apply-templates>
</ul>
</li>
</xsl:template>
<xsl:template match="BlogPost" mode="month">
<xsl:variable name="vMonth" select=
"substring(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
6,2)"/>
<xsl:variable name="vmonthsBlogs" select=
"key('kPostsByYearMonth',
substring(
concat(archiveUnder,
@createDate[not(archiveUnder)]
),
1,7)
)"/>
<li><xsl:value-of select=
"concat($vMonthNames[position()=$vMonth],
' (',
count($vmonthsBlogs),
')'
)"/>
</li>
</xsl:template>
</xsl:stylesheet>
应用于提供的示例XML文档(我们正在访问$currentPage
<xsl:param>
以外的每个节点,因为这将在真正的Umbraco案例中),格式化以便于阅读每个createDate
的{{1}}属性在元素名称后面的第一行上移动:
BlogPost
产生想要的正确结果:
<Blog id="1078" parentID="1049" level="2" writerID="0" creatorID="0" nodeType="1073" template="1089" sortOrder="7" createDate="2010-09-27T14:11:04" updateDate="2010-10-12T16:59:12" nodeName="Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078" isDoc="">
<newPageTitle>The Lorem Ipsum Blog</newPageTitle>
<BlogCentre id="1079" parentID="1078" level="3" writerID="0" creatorID="0" nodeType="1075" template="1076" sortOrder="1" createDate="2010-09-27T14:11:49" updateDate="2010-10-07T14:43:13" nodeName="Blog Centre 1" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079" isDoc="">
<Room id="1081" parentID="1079" level="4" writerID="0" creatorID="0" nodeType="1077" template="0" sortOrder="1" createDate="2010-09-27T14:12:26" updateDate="2010-10-07T14:43:06" nodeName="Room 10" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1081" isDoc="">
<BlogPost id="1175" parentID="1081" level="5"
createDate="2010-10-07T14:51:48"
writerID="0" creatorID="0" nodeType="1087"
template="1192" sortOrder="1"
updateDate="2010-10-12T21:30:53"
nodeName="The first ever Blog post"
writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1175" isDoc="">
<topicTitle>The first ever blog</topicTitle>
<archiveUnder/>
</BlogPost>
<BlogPost id="1180" parentID="1081"
createDate="2010-10-08T15:52:20"
level="5" writerID="0" creatorID="3"
nodeType="1087" template="1089"
sortOrder="2"
updateDate="2010-10-12T16:57:00" nodeName="asdasd"
writerName="Administrator" creatorName="ZX"
path="-1,1049,1078,1079,1081,1180" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
<BlogPost id="1181" parentID="1081" level="5"
createDate="2010-10-08T17:50:19"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="3"
updateDate="2010-10-12T11:40:37"
nodeName="condimentum"
writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1181" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-09-01T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1194" parentID="1081" level="5"
createDate="2010-10-12T11:41:50"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="4"
updateDate="2010-10-12T11:42:37"
nodeName="Nam augue" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1194" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-08-05T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1195" parentID="1081" level="5"
createDate="2010-10-12T11:42:15"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="5"
updateDate="2010-10-12T11:42:25"
nodeName="consequat nunc"
writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1195" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-08-12T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1196" parentID="1081" level="5"
createDate="2010-10-12T12:05:57"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="6"
updateDate="2010-10-12T12:08:40"
nodeName="cursus congue"
writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1196" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2009-10-22T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1197" parentID="1081" level="5"
createDate="2010-10-12T12:08:54"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="7"
updateDate="2010-10-12T12:09:24"
nodeName="inceptos" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1197" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2009-11-19T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1198" parentID="1081" level="5"
createDate="2010-10-12T12:09:45"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="8"
updateDate="2010-10-12T12:10:13"
nodeName="inceptos himenaeos"
writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1198" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2009-12-16T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1199" parentID="1081" level="5"
createDate="2010-10-12T12:10:29"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="9"
updateDate="2010-10-12T12:10:56"
nodeName="consequat" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1199" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-01-13T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1200" parentID="1081" level="5"
createDate="2010-10-12T12:11:08"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="10"
updateDate="2010-10-12T12:11:35"
nodeName="himenaeos" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1200" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-02-09T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1201" parentID="1081" level="5"
createDate="2010-10-12T12:11:45"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="11"
updateDate="2010-10-12T12:12:35"
nodeName="cursus congue" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1201" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-04-22T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1202" parentID="1081" level="5"
createDate="2010-10-12T12:12:18"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="12"
updateDate="2010-10-12T12:12:45" nodeName="pharetra"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1079,1081,1202" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-03-09T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1203" parentID="1081" level="5"
createDate="2010-10-12T12:13:05"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="13"
updateDate="2010-10-12T12:13:27"
nodeName="inceptos himenaeos"
writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1203" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-05-26T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1204" parentID="1081" level="5"
createDate="2010-10-12T12:13:36"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="14"
updateDate="2010-10-12T12:13:56"
nodeName="pharetra" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1204" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-06-11T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1205" parentID="1081" level="5"
createDate="2010-10-12T12:14:06"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="15"
updateDate="2010-10-12T12:14:41"
nodeName="Fusce augue" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1205" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-07-08T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1206" parentID="1081" level="5"
createDate="2010-10-12T12:14:52"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="16"
updateDate="2010-10-12T12:15:19"
nodeName="pharetra et fermentum"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1079,1081,1206" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-08-09T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1207" parentID="1081"
createDate="2010-10-12T12:15:31"
level="5" writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="17"
updateDate="2010-10-12T12:15:51"
nodeName="Fusce augue purus" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1207" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-09-14T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1208" parentID="1081" level="5"
createDate="2010-10-12T12:16:25"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="18"
updateDate="2010-10-12T12:16:45"
nodeName="Class aptent taciti" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1079,1081,1208" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-06-04T00:00:00</archiveUnder>
</BlogPost>
<BlogPost id="1209" parentID="1081" level="5"
createDate="2010-10-12T12:17:01"
writerID="0" creatorID="0" nodeType="1087"
template="1089" sortOrder="19"
updateDate="2010-10-12T12:17:29" nodeName="Class aptent"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1079,1081,1209" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
<archiveUnder>2010-06-21T00:00:00</archiveUnder>
</BlogPost>
</Room>
<Room id="1082" parentID="1079" level="4"
createDate="2010-09-27T14:12:33"
writerID="0" creatorID="0" nodeType="1077" template="0"
sortOrder="2"
updateDate="2010-10-07T14:43:09" nodeName="Test Blog"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1079,1082" isDoc="">
<BlogPost id="1182" parentID="1082" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="1" createDate="2010-10-08T17:51:19" updateDate="2010-10-08T17:51:58" nodeName="Test Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1082,1182" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
<Room id="1083" parentID="1079" level="4" writerID="0"
createDate="2010-09-27T14:12:40"
creatorID="0" nodeType="1077" template="1089" sortOrder="3"
updateDate="2010-10-07T14:49:48" nodeName="Test Blog"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1079,1083" isDoc="">
<BlogPost id="1183" parentID="1083" level="5" writerID="0" creatorID="0" nodeType="1087" template="1089" sortOrder="1" createDate="2010-10-08T17:52:22" updateDate="2010-10-08T17:52:39" nodeName="Test Blog" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1079,1083,1183" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
</BlogCentre>
<BlogCentre id="1080" parentID="1078" level="3" writerID="0"
createDate="2010-09-27T14:11:55"
creatorID="0" nodeType="1075" template="1076" sortOrder="2"
updateDate="2010-10-07T14:43:23" nodeName="Blog Centre 2"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1080" isDoc="">
<Room id="1084" parentID="1080" level="4" writerID="0" creatorID="0" nodeType="1077" template="0" sortOrder="1" createDate="2010-09-27T14:12:45" updateDate="2010-10-07T14:43:17" nodeName="Room 1" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1084" isDoc="">
<BlogPost id="1184" parentID="1084" level="5" writerID="0"
createDate="2010-10-08T17:53:05"
creatorID="0" nodeType="1087" template="1089" sortOrder="1"
updateDate="2010-10-08T17:53:29" nodeName="Blog Post 3"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1080,1084,1184" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
<Room id="1085" parentID="1080" level="4" writerID="0"
createDate="2010-09-27T14:12:50"
creatorID="0" nodeType="1077" template="0" sortOrder="2"
updateDate="2010-10-07T14:43:19" nodeName="Room 2"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1080,1085" isDoc="">
<BlogPost id="1185" parentID="1085" level="5" writerID="0"
createDate="2010-10-08T17:53:51"
creatorID="0" nodeType="1087" template="1089" sortOrder="1"
updateDate="2010-10-08T17:54:15" nodeName="Blog Post 109"
writerName="Administrator" creatorName="Administrator"
path="-1,1049,1078,1080,1085,1185" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
<Room id="1086" parentID="1080" level="4" writerID="0" creatorID="0" nodeType="1077" template="1089" sortOrder="3" createDate="2010-09-27T14:12:55" updateDate="2010-10-07T14:50:39" nodeName="Room 3" writerName="Administrator" creatorName="Administrator" path="-1,1049,1078,1080,1086" isDoc="">
<BlogPost id="1186" parentID="1086" level="5" writerID="0"
createDate="2010-10-08T17:54:28"
creatorID="0" nodeType="1087" template="1089" sortOrder="1"
updateDate="2010-10-08T17:54:51"
nodeName="Blog Post 123" writerName="Administrator"
creatorName="Administrator"
path="-1,1049,1078,1080,1086,1186" isDoc="">
<topicTitle>Lorem Ipsum</topicTitle>
</BlogPost>
</Room>
</BlogCentre>
</Blog>
请注意:
Muenchian Grouping - 用于确定不同年份和确定每年的不同月份。
使用表达式在<ul>
<li>
<h3>2010</h3>
<ul>
<li>October (7)</li>
<li>September (2)</li>
<li>August (3)</li>
<li>July (1)</li>
<li>June (3)</li>
<li>May (1)</li>
<li>April (1)</li>
<li>March (1)</li>
<li>February (1)</li>
<li>January (1)</li>
</ul>
</li>
<li>
<h3>2009</h3>
<ul>
<li>December (1)</li>
<li>November (1)</li>
<li>October (1)</li>
</ul>
</li>
</ul>
属性和createDate
子项之间选择日期:
concat(archiveUnder,@ createDate [not(archiveUnder)])
如果archiveUnder
缺失或为空,则此连接仅选择@createDate
。
0.3。 即使元素的日期未排序,转换也会产生正确的结果。
答案 1 :(得分:2)
如Jeni Tennison所述,这将是一个两步法:
我们可以使用以下XPath表达式获取第一部分:
BlogPost[not (substring(@createDate, 1, 7)
= substring(preceding-sibling::*[1]/@createDate, 1, 7))]
然后,对于第二部分,我们需要使用count()
函数计算帖子:
BlogPost[not (substring(@createDate, 1, 7)
= substring(preceding-sibling::*[1]/@createDate, 1, 7))]
在我们的XSLT中,我们可以使用如下表达式:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Room">
<ul>
<xsl:for-each select="BlogPost[not (substring(@createDate, 1, 7) = substring(preceding-sibling::*[1]/@createDate, 1, 7))]">
<xsl:sort select="@createDate" order="descending"/>
<li>
<xsl:value-of select="substring(@createDate, 1, 7)"/>
<xsl:text>(</xsl:text>
<xsl:value-of select="count(//BlogPost[substring(@createDate, 1, 7) = substring(current()/@createDate, 1, 7)]) "/>
<xsl:text>)</xsl:text>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
上面的样式表只是按月工作,不考虑多年。为了支持多年,您可以添加一个额外的步骤来获得独特的年份:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Room">
<ul>
<xsl:for-each select="BlogPost[not (substring(@createDate, 1, 4) = substring(preceding-sibling::*[1]/@createDate, 1, 4))]">
<xsl:sort select="@createDate" order="descending"/>
<li>
<xsl:value-of select="substring(@createDate, 1, 4)"/>
<ul>
<xsl:for-each select="//BlogPost[substring(@createDate, 1, 4) = substring(current()/@createDate, 1, 4) and not (substring(@createDate, 1, 7) = substring(preceding-sibling::*[1]/@createDate, 1, 7))]">
<xsl:sort select="@createDate" order="descending"/>
<li>
<xsl:value-of select="substring(@createDate, 1, 7)"/>
<xsl:text>(</xsl:text>
<xsl:value-of select="count(//BlogPost[substring(@createDate, 1, 7) = substring(current()/@createDate, 1, 7)]) "/>
<xsl:text>)</xsl:text>
</li>
</xsl:for-each>
</ul>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:2)
此样式表:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:m="month"
exclude-result-prefixes="m">
<xsl:param name="currentPage" select="/Blog"/>
<xsl:key name="kBlogPostByYear" match="BlogPost"
use="substring((@createDate|archiveUnder)[last()],1,4)"/>
<xsl:key name="kBlogPostByYearMonth" match="BlogPost"
use="substring((@createDate|archiveUnder)[last()],1,7)"/>
<m:month>January</m:month>
<m:month>February</m:month>
<m:month>March</m:month>
<m:month>April</m:month>
<m:month>May</m:month>
<m:month>June</m:month>
<m:month>July</m:month>
<m:month>August</m:month>
<m:month>September</m:month>
<m:month>October</m:month>
<m:month>November</m:month>
<m:month>December</m:month>
<xsl:variable name="vMonth" select="document('')/*/m:*"/>
<xsl:template match="/">
<ul>
<xsl:apply-templates
select="$currentPage/*/*/BlogPost
[count(.|key('kBlogPostByYear',
substring((@createDate|
archiveUnder)
[last()],
1,
4))[1])=1]">
<xsl:sort select="substring((@createDate|archiveUnder)
[last()],
1,4)" order="descending"/>
</xsl:apply-templates>
</ul>
</xsl:template>
<xsl:template match="BlogPost">
<xsl:variable name="vYear" select="substring((@createDate|
archiveUnder)[last()],
1,
4)"/>
<ul>
<h3>
<xsl:value-of select="$vYear"/>
</h3>
<ul>
<xsl:apply-templates
select="$currentPage/*/*/BlogPost
[generate-id() =
generate-id(
key('kBlogPostByYearMonth',
concat($vYear,'-',
substring(
(@createDate|
archiveUnder)
[last()],
6,
2))))]"
mode="month">
<xsl:sort select="substring((@createDate|archiveUnder)
[last()],
6,2)" order="descending"/>
</xsl:apply-templates>
</ul>
</ul>
</xsl:template>
<xsl:template match="BlogPost" mode="month">
<xsl:variable name="vDate"
select="(@createDate|archiveUnder)[last()]"/>
<li>
<xsl:value-of select="concat($vMonth
[number(
substring($vDate,
6,
2))],
' (',
count(key('kBlogPostByYearMonth',
substring($vDate,1,7))),
')')"/>
</li>
</xsl:template>
</xsl:stylesheet>
输出:
<ul>
<ul>
<h3>2010</h3>
<ul>
<li>October (7)</li>
<li>September (2)</li>
<li>August (3)</li>
<li>July (1)</li>
<li>June (3)</li>
<li>May (1)</li>
<li>April (1)</li>
<li>March (1)</li>
<li>February (1)</li>
<li>January (1)</li>
</ul>
</ul>
<ul>
<h3>2009</h3>
<ul>
<li>December (1)</li>
<li>November (1)</li>
<li>October (1)</li>
</ul>
</ul>
</ul>
编辑3 :抱歉,我错过了排序。现在补充说。此外,具有$currentPage
参数的小型重构。