2

ヘッダーを出力できるように、cityとcurrent-date()の両方に該当するグループ内のイベントをテストしたいと思います。

都市を見つけるには($ place eq // event / @ city)はうまくいくようです。しかし、「あるeventTime /@dateが$today未満である」という表現方法がわかりません。エラーメッセージは「'eq'の第2オペランドとして複数の項目のシーケンスを使用することはできません」です。これは、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出力がどうあるべきかという例はありませんが、あなたが何を達成しようとしているのかはわかると確信しています。

xsl:ifテストを行うためにとを削除し、xsl:choose述語を追加することで、XSLTを簡略化できると思います。

このXSLT2.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 に答える