我正在开发一个网页,该页面发布基于XML提要的演示文稿,而我没有权限进行更改。
提要如下所示:
<track name="Track 1">
<session name="Session 1" starttime="2012-06-06 10:45" endtime="2012-06-06 12:45">
<presentation name="Presentation 1">
...presentation info
</presentation>
<presentation name="Presentation 2">
...presentation info
</presentation>
</session>
<session name="Session 2" starttime="2012-06-06 10:45" endtime="2012-06-06 12:45">
<presentation name="Presentation 3">
...presentation info
</presentation>
<presentation name="Presentation 4">
...presentation info
</presentation>
</session>
<session name="Session 3" starttime="2012-06-07 08:45" endtime="2012-06-07 10:45">
<presentation name="Presentation 5">
...presentation info
</presentation>
<presentation name="Presentation 6">
...presentation info
</presentation>
</session>
</track>目前,我正在做一个<xsl:for-each select="session">循环来提取信息,但是最后我输出了重复的日期和时间。
我做实际的日期和时间解析没有问题,所以我目前正在输出2012年6月6日;10:45,没有问题,但是由于for- each,每次都会复制,如下所示:
2012年6月6日
10:45-12:45
第1次会议:专题介绍1,2
2012年6月6日
10:45-12:45
第2次会议:专题介绍3、专题介绍4
2012年6月7日:
8:45-10:45
第3次会议:专题介绍5,专题介绍6
我想要的是以某种方式提取出所有常见的日期时间,例如,获得如下输出:
2012年6月6日:
10:45-12:45
会话1:演示文稿1,演示文稿2
会话2:演示文稿3,演示文稿4
2012年6月7日:
8:45-10:45
第3次会议:专题介绍5,专题介绍6
作为参考,以下是我目前的实现:
<xsl:for-each select="session">
<h4>
<!-- output to Month, DD, YYYY -->
<xsl:call-template name="formatDate">
<xsl:with-param name="dateTime" select="@starttime" />
</xsl:call-template>
</h4>
<h5>
<!-- output time -->
<xsl:call-template name="formatTime">
<xsl:with-param name="dateTime" select="@starttime" />
</xsl:call-template> -
<xsl:call-template name="formatTime">
<xsl:with-param name="dateTime" select="@endtime" />
</xsl:call-template>
</h5>
<!-- session title -->
<h5><xsl:value-of select="@name"/></h5>
<!-- presentation title -->
<xsl:for-each select="presentation">
<xsl:value-of select="@name"/><xsl:element name="br"/>
</xsl:for-each>
</xsl:for-each>以及日期时间格式化程序:
<!-- formatting dateTime -->
<xsl:template name="formatDate">
<xsl:param name="dateTime" />
<xsl:variable name="date" select="substring-before($dateTime, ' ')" />
<xsl:variable name="year" select="substring-before($date, '-')" />
<xsl:variable name="month" select="number(substring-before(substring-after($date, '-'), '-'))" />
<xsl:variable name="day" select="number(substring-after(substring-after($date, '-'), '-'))" />
<!-- output -->
<xsl:choose>
<xsl:when test="$month = '1'">January</xsl:when>
<xsl:when test="$month = '2'">February</xsl:when>
<xsl:when test="$month = '3'">March</xsl:when>
<xsl:when test="$month = '4'">April</xsl:when>
<xsl:when test="$month = '5'">May</xsl:when>
<xsl:when test="$month = '6'">June</xsl:when>
<xsl:when test="$month = '7'">July</xsl:when>
<xsl:when test="$month = '8'">August</xsl:when>
<xsl:when test="$month = '9'">September</xsl:when>
<xsl:when test="$month = '10'">October</xsl:when>
<xsl:when test="$month = '11'">November</xsl:when>
<xsl:when test="$month = '12'">December</xsl:when>
</xsl:choose>
<xsl:value-of select="' '" />
<xsl:value-of select="$day" />
<xsl:value-of select="', '" />
<xsl:value-of select="$year" />
</xsl:template>
<!-- formatting dateTime -->
<xsl:template name="formatTime">
<xsl:param name="dateTime" />
<xsl:value-of select="substring-after($dateTime, ' ')" />
</xsl:template>发布于 2012-07-03 18:17:15
您希望使用Muenchian法进行分组。将其立即添加到样式表的根元素中:
<xsl:key name="sessions-by-track-name-starttime-and-endtime" match="/track/session" use="concat(parent::track/@name, ' ', @starttime, ' ', @endtime)"/>然后更新XSLT,如下所示:
<xsl:for-each select="session[generate-id() = generate-id(key('sessions-by-track-name-starttime-and-endtime', concat(parent::track/@name, ' ', @starttime, ' ', @endtime))[1])]">
<h4>
<!-- output to Month, DD, YYYY -->
<xsl:call-template name="formatDate">
<xsl:with-param name="dateTime" select="@starttime" />
</xsl:call-template>
</h4>
<h5>
<!-- output time -->
<xsl:call-template name="formatTime">
<xsl:with-param name="dateTime" select="@starttime" />
</xsl:call-template> -
<xsl:call-template name="formatTime">
<xsl:with-param name="dateTime" select="@endtime" />
</xsl:call-template>
</h5>
<xsl:for-each select="key('sessions-by-track-name-starttime-and-endtime', concat(parent::track/@name, ' ', @starttime, ' ', @endtime))">
<!-- session title -->
<h5><xsl:value-of select="@name"/></h5>
<!-- presentation title -->
<xsl:for-each select="presentation">
<xsl:value-of select="@name"/><xsl:element name="br"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>发布于 2012-07-03 18:10:33
首先,避免使用XSLT中的for-each,而是将节点应用于模板。
尝试这个(压缩,不调用call-template,因为您没有发布该位),您可以在这个XMLPlayground上运行它。
<!-- sessions -->
<xsl:template match='track/session'>
<xsl:if test='not(preceding-sibling::session[@starttime = current()/@starttime])'>
<h4><xsl:value-of select="@starttime" /></h4>
<h5><xsl:value-of select="concat(@starttime,' - ',@endtime)" /></h5>
<p><xsl:apply-templates select="presentation" /></p>
<xsl:variable name='other_pres' select="following-sibling::session[@starttime = current()/@starttime]/presentation" />
<xsl:if test='count($other_pres)'>
<p><xsl:apply-templates select="$other_pres" /></p>
</xsl:if>
</xsl:if>
</xsl:template>
<!-- presentations -->
<xsl:template match='presentation'>
<xsl:if test='position() = 1'>
<strong><xsl:value-of select='../@name' />: </strong>
</xsl:if>
<xsl:value-of select="@name"/>
<xsl:if test='position() != last()'>, </xsl:if>
</xsl:template>这里的概念是,在session模板中,对于每个会话,我们首先查看以前是否已经使用相同的@starttime处理过会话(因为我假设这是您所指的负责复制的属性)。如果是的话,我们就跳过了。
然后,在输出会话的演示文稿(您会注意到,这些演示文稿由他们自己的模板处理)时,我们还会处理当前session的兄弟节点的任何表示。
输出 (没有访问日期格式模板的权限)
<h4>2012-06-06 10:45</h4>
<h5>2012-06-06 10:45 - 2012-06-06 12:45</h5>
<p><strong>Session 1: </strong>Presentation 1, Presentation 2</p><p><strong>Session 2: </strong>Presentation 3, Presentation 4</p>
<h4>2012-06-07 08:45</h4>
<h5>2012-06-07 08:45 - 2012-06-07 10:45</h5>
<p><strong>Session 3: </strong>Presentation 5, Presentation 6</p>https://stackoverflow.com/questions/11316208
复制相似问题