我想测试符合city和current-date()条件的组内的事件,以便我可以输出标题。
找到城市($ place eq // event / @ city)似乎有效。但是我无法弄清楚如何表达"某些eventTime / @ date小于$ today"。错误消息是"不允许多个项目的序列作为' eq'"的第二个操作数。这是令人困惑的,因为我写过test ="($ place eq // event / @ city)和(xs:date($ today)lt xs:date(// eventTime / @ date))。
我应该如何在今天的eventTime中将$今天与@date进行比较?这是输入。
<calendar>
<group month="2012-04-01">
<event city="paris">
<eventTime date="2012-04-02"/>
<eventText>Paris - expired April date</eventText>
</event>
<event city="london">
<eventTime date="2012-04-19"/>
<eventText>London - current April 19 date</eventText>
</event>
<event city="london">
<eventTime date="2012-04-24"/>
<eventText>London - current April date</eventText>
</event>
</group>
<group month="2012-05-01">
<event city="london">
<eventTime date="2012-05-02"/>
<eventText>London - current May date</eventText>
</event>
<event city="paris">
<eventTime date="2012-05-01"/>
<eventText>Paris - current May date</eventText>
</event>
<event city="london">
<eventTime date="2012-05-02"/>
<eventText>London - current May date</eventText>
</event>
</group>
</calendar>
这是XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://johnadamturnbull.com/xslt"
exclude-result-prefixes="xs"
version="2.0" >
<xsl:output method="html" indent="yes" name="html"/>
<xsl:param name="place" as="xs:string" required="yes"></xsl:param>
<xsl:variable name="today" select="current-date()" as="xs:date"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="calendar/group"/>
</body>
</html>
</xsl:template>
<xsl:template match = "group">
<xsl:if test="($place eq //event/@city) and
(xs:date($today) ge xs:date(//eventTime/@date))">
<h4 class = "dateHeader">
<xsl:value-of select="format-date(./@month,'[MNn] [Y]')"/>
</h4>
<ul>
<xsl:apply-templates select="event"></xsl:apply-templates>
</ul>
</xsl:if>
</xsl:template>
<xsl:template match="event">
<xsl:variable name="eventTime" select="eventTime/@date" as="xs:date"/>
<xsl:choose>
<xsl:when test="($eventTime ge $today) and
(($place eq @city) or (@city eq ''))">
<li>
<xsl:apply-templates></xsl:apply-templates>
</li>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
没有HTML输出应该是什么的例子,但我非常确定我能说出你想要实现的目标。
我认为您可以通过删除xsl:if
和xsl:choose
以及添加谓词来简化您的XSLT。
这个XSLT 2.0样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://johnadamturnbull.com/xslt" exclude-result-prefixes="xs fn" version="2.0">
<xsl:output method="html" indent="yes" name="html"/>
<xsl:strip-space elements="*"/>
<xsl:param name="place" as="xs:string" required="yes"/>
<xsl:variable name="today" select="current-date()" as="xs:date"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="calendar/group"/>
</body>
</html>
</xsl:template>
<!--Match group if @city matches $place or is empty and has an eventTime
with a @date that is greater than or equal to today's date.-->
<xsl:template match="group[event[@city=$place or @city=''][xs:date(eventTime/@date) >= $today]]">
<h4 class="dateHeader">
<xsl:value-of select="format-date(@month,'[MNn] [Y]')"/>
</h4>
<ul>
<!--Only apply-templates to events that have a @city that matches $place
or has a @city that is empty.-->
<xsl:apply-templates select="event[@city=$place or @city='']"/>
</ul>
</xsl:template>
<!--Only match events that have an eventTime with a @date that is greater than
or equal to today's date.-->
<xsl:template match="event[@city=$place or @city=''][xs:date(eventTime/@date) >= $today]">
<li>
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template match="event"/>
</xsl:stylesheet>
应用于您的示例XML输入生成此HTML输出:
<html>
<body>
<h4 class="dateHeader">April 2012</h4>
<ul>
<li>London - current April 19 date</li>
<li>London - current April date</li>
</ul>
<h4 class="dateHeader">May 2012</h4>
<ul>
<li>London - current May date</li>
<li>London - current May date</li>
</ul>
</body>
</html>
如果这不是您要查找的内容,请添加HTML输出的示例。