满足计算值的项目的XSLT计数

时间:2011-12-13 23:08:54

标签: variables xslt foreach

我有一组XML数据,我正在尝试通过这些数据来确定有多少项目的日期不到1周。

DATA:

<events>
    <event>
        <eventDate>20110504</date>
        <description>whatever</description>
    </event>
    <event>
        <eventDate>20110720</date>
        <description>whatever</description>
    </event>
    .
    .
    .
    <event>
        <eventDate>20111210</date>
        <description>whatever</description>
    </event>
</events>

XSLT:

<xsl:variable name="events" select="sc:item('/sitecore/content/Home/Upcoming Events',.)" />
<xsl:variable name="now" select="dateutil:get_IsoNow()" />
<xsl:variable name="counter" select="0" />
<xsl:template match="*">
    <xsl:apply-templates select="$sc_item" mode="main"/>
</xsl:template>
<xsl:template match="*" mode="main">
    <xsl:choose>
        <xsl:when test="count($events/item) &gt; 0">
            <xsl:for-each select="$events/item">
                <xsl:sort select="sc:fld('eventDate',.)" order="ascending"/>
                <xsl:variable name="date_difference">
                    <xsl:call-template name="date-difference">
                        <xsl:with-param name="item-year" select="substring(sc:fld('eventDate',.),1,4)" />
                        <xsl:with-param name="item-month" select="substring(sc:fld('eventDate',.),5,2)" />
                        <xsl:with-param name="item-day" select="substring(sc:fld('eventDate',.),7,2)" />
                        <xsl:with-param name="today-year" select="substring(substring($now,1,8),1,4)" />
                        <xsl:with-param name="today-month" select="substring(substring($now,1,8),5,2)" />
                        <xsl:with-param name="today-day" select="substring(substring($now,1,8),7,2)" />
                    </xsl:call-template>
                </xsl:variable>
                <xsl:if test="($date_difference &lt; 8)">
                    <p>
                        <sc:text field="eventDate" /><br />
                        <sc:text field="description" />
                    </p>
            ****  Increment a counter variable  ****
                    $counter++

                </xsl:if>
            </xsl:for-each>

            ****  Check the counter variable  ****
            <xsl:if test="($counter = 0)">
                <p>No upcoming events are scheduled at this time.</p>
            </xsl:if>

        </xsl:when>
        <xsl:otherwise>
            <p>No upcoming events are scheduled at this time.</p>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>


<xsl:template name="date-difference">
    <xsl:param name="item-year" />
    <xsl:param name="item-month" />
    <xsl:param name="item-day" />
    <xsl:param name="today-year" />
    <xsl:param name="today-month" />
    <xsl:param name="today-day" />
    <xsl:variable name="jul-item">
        <xsl:call-template name="calculate-julian-day">
            <xsl:with-param name="year" select="$item-year" />
            <xsl:with-param name="month" select="$item-month" />
            <xsl:with-param name="day" select="$item-day" />
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="jul-today">
        <xsl:call-template name="calculate-julian-day">
            <xsl:with-param name="year" select="$today-year" />
            <xsl:with-param name="month" select="$today-month" />
            <xsl:with-param name="day" select="$today-day" />
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$jul-today - $jul-item" />
</xsl:template>


<xsl:template name="calculate-julian-day">
    <xsl:param name="year" />
    <xsl:param name="month" />
    <xsl:param name="day" />
    <xsl:variable name="a" select="floor((14 - $month) div 12)" />
    <xsl:variable name="y" select="$year + 4800 - $a" />
    <xsl:variable name="m" select="$month + 12 * $a - 3" />
    <xsl:value-of select="$day + floor((153 * $m + 2) div 5) + $y * 365 + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
</xsl:template>

我知道我无法在XSLT中更改变量的值,因为它们实际上是常量。

我知道我需要使用某种递归。

我无法弄清楚如何做到这一点......我真的很难过。

有人可以帮忙吗?

4 个答案:

答案 0 :(得分:0)

您无法确定“一周前”日期的字符串值,然后使用XPath进行文本比较吗?

count(string(event/eventDate) > $oneweekagodatestring)

答案 1 :(得分:0)

在您的代码中替换

                  L o n g    C o d e
        ****  Increment a counter variable  **** 
              $counter++ 

<强>与

  <xsl:variable name="vHits">
    L o n g    C o d e
    <!-- If the condition is true -->
    <xsl:text>1</xsl:text>
  </xsl:variable>

和此代码

        ****  Check the counter variable  ****                    
     <xsl:if test="($counter = 0)">                        
      <p>No upcoming events are scheduled at this time.</p>                    
     </xsl:if>  

<强>与

     <xsl:if test="(string-length($vHits = 0)">                        
      <p>No upcoming events are scheduled at this time.</p>                    
     </xsl:if>  

完整的代码示例

此转换演示了使用XSLT进行“反减少”计算:)

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <xsl:variable name="vHits">
   <xsl:apply-templates/>
  </xsl:variable>

  <xsl:value-of select="string-length($vHits)"/>

  <xsl:text> numbers fulfil x^2 &lt;= 10</xsl:text>
 </xsl:template>

 <xsl:template match="num">
  <xsl:if test="not(. * . > 10)">1</xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于此XML文档

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

产生了想要的正确结果

3 numbers fulfil x^2 <= 10

答案 2 :(得分:0)

如果您使用的是Sitecore,您可以随时使用某些内置日期函数来获取yearmonthday,而无需借助处理子字符串等。

<xsl:variable name="selectedDate">20111212</xsl:variable>
<xsl:variable name="isoSelectedDate" select="date:ToIsoDate(date:ParseDateTime($selectedDate,date:IsoDateToDateTime(sc:isoNow())))"/>

<xsl:variable name="day" select="sc:day($isoSelectedDate)"/>
<xsl:variable name="month" select="sc:month($isoSelectedDate)"/>
<xsl:variable name="year" select="sc:year($isoSelectedDate)"/>

我认为Dimitre的答案效果很好,但这可能会略微增加可读性:)

答案 3 :(得分:0)

我最终使用了“一周前”的约会建议。为“$ oneweekagodatestring”创建变量模板需要花费大量的工作。但是,我得到了它的工作:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:sc="http://www.sitecore.net/sc" 
  xmlns:dot="http://www.sitecore.net/dot" 
  xmlns:dateutil="http://www.sitecore.net/dateutil" 
  exclude-result-prefixes="dot sc dateutil">

<!-- output directives -->
<xsl:output method="html" indent="no" encoding="UTF-8" />

<!-- parameters -->
<xsl:param name="lang" select="''"/>
<xsl:param name="id" select="''"/>
<xsl:param name="sc_item"/>
<xsl:param name="sc_currentitem"/>

<!-- variables -->
<xsl:variable name="events" select="sc:item('/sitecore/content/Home/About/News Center/Upcoming Events',.)" />
<xsl:variable name="now" select="dateutil:get_IsoNow()" />

<!-- entry point -->
<xsl:template match="*">
    <xsl:apply-templates select="$sc_item" mode="main"/>
</xsl:template>

<!--==============================================================-->
<!-- main                                                         -->
<!--==============================================================-->
<xsl:template match="*" mode="main">
    <xsl:variable name="current_date">
        <xsl:call-template name="adjust-date">
            <xsl:with-param name="date" select="substring-before($now,'T')"/>
            <xsl:with-param name="days" select="-7"/>
        </xsl:call-template>
    </xsl:variable>

    <xsl:choose>
        <xsl:when test="count($events/item[sc:fld('Event Title',.)!='' and substring-before(sc:fld('Event Date',.),'T') &gt; $current_date]) &gt; 0">
            <xsl:for-each select="$events/item[sc:fld('Event Title',.)!='' and substring-before(sc:fld('Event Date',.),'T') &gt; $current_date]">
                <xsl:sort select="sc:fld('Event Date',.)" order="ascending"/>
                <p>Output for event information goes here.</p>
            </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>
            <p>No upcoming events are scheduled at this time.</p>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>


<!--======================================================================-->
<!-- Add or subtract days to or from a date                               -->
<!--                                                                      -->
<!-- This template is from Boris Gomiunik. I found it here:               -->
<!-- http://www.sharepointboris.net/2008/11/xsl-template-for-adding-days/ -->
<!--======================================================================-->
<xsl:template name="adjust-date">
    <xsl:param name="date"/>
    <xsl:param name="days"/>
    <xsl:param name="oldMonth"><xsl:value-of select="substring($date,5,2)"/></xsl:param>
    <xsl:param name="oldYear"><xsl:value-of select="substring($date,1,4)"/></xsl:param>
    <xsl:param name="oldDay"><xsl:value-of select="substring($date,7,2)"/></xsl:param>
    <xsl:param name="newMonth">
        <xsl:choose>
            <xsl:when test="$oldMonth = '01'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 31">01</xsl:when>
                    <xsl:otherwise>02</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '02'">
                <xsl:choose>
                    <xsl:when test="($oldYear mod 4 = 0 and number($oldDay) + $days &lt;= 29) or ($oldYear mod 4 != 0 and number($oldDay) + $days &lt;= 28)">02</xsl:when>
                    <xsl:otherwise>03</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '03'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 31">03</xsl:when>
                    <xsl:otherwise>04</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '04'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 30">04</xsl:when>
                    <xsl:otherwise>05</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '05'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 31">05</xsl:when>
                    <xsl:otherwise>06</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '06'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 30">06</xsl:when>
                    <xsl:otherwise>07</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '07'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 31">07</xsl:when>
                    <xsl:otherwise>08</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '08'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 31">08</xsl:when>
                    <xsl:otherwise>09</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '09'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 30">09</xsl:when>
                    <xsl:otherwise>10</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '10'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 31">10</xsl:when>
                    <xsl:otherwise>11</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '11'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 30">11</xsl:when>
                    <xsl:otherwise>12</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '12'">
                <xsl:choose>
                    <xsl:when test="number($oldDay) + $days &lt;= 31">12</xsl:when>
                    <xsl:otherwise>01</xsl:otherwise>
                </xsl:choose>
            </xsl:when>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="newYear">
        <xsl:choose>
            <xsl:when test="$oldMonth = '12' and (number($oldDay) + $days) &gt;= 31"><xsl:value-of select="number($oldYear) + 1"/></xsl:when>
            <xsl:otherwise><xsl:value-of select="$oldYear"/></xsl:otherwise>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="newDay">
        <xsl:choose>
            <xsl:when test="$oldMonth = '01'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '02'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise>
                        <xsl:choose>
                            <xsl:when test="$oldYear mod 4 = 0">
                                <xsl:value-of select="number($oldDay) + $days - 29"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="number($oldDay) + $days - 28"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '03'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '04'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '05'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '06'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '07'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '08'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '09'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '10'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '11'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$oldMonth = '12'">
                <xsl:choose>
                    <xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
                </xsl:choose>
            </xsl:when>
        </xsl:choose>
    </xsl:param>
    <xsl:value-of select="$newYear"/>
    <xsl:value-of select="$newMonth" />
    <xsl:if test="$newDay &lt; 10">0</xsl:if><xsl:value-of select="$newDay"/>
</xsl:template>

</xsl:stylesheet>