2

我想测试一个符合 city 和 current-date() 的组中的事件,以便我可以输出一个标题。

查找城市 ($place eq //event/@city) 似乎可行。但我不知道如何表达“某些 eventTime/@date 小于 $today”。错误消息是“不允许将多个项目的序列作为 'eq' 的第二个操作数”这令人困惑,因为我已经编写了 test="($place eq //event/@city) 和 (xs: date($today) lt xs:date(//eventTime/@date))。

我应该如何将 $today 与 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>
4

1 回答 1

1

没有 HTML 输出应该是什么的示例,但我很确定我可以说出您想要实现的目标。

我认为您的 XSLT 可以通过删除和添加谓词来进行测试来xsl:if简化xsl:choose

这个 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 输出应该是什么样子的示例。

于 2012-04-19T19:04:06.907 回答