XSLT количество элементов, удовлетворяющих расчетному значению - PullRequest
1 голос
/ 14 декабря 2011

У меня есть набор данных XML, которые я пытаюсь просмотреть и определить, сколько элементов имеют дату менее 1 недели.

ДАННЫЕ:

<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 голосов
/ 15 декабря 2011

Я закончил тем, что использовал предложение даты "одна неделя назад". Для создания шаблона для создания переменной "$ 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>
0 голосов
/ 14 декабря 2011

Замените в своем коде это :

                  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
0 голосов
/ 14 декабря 2011

Если вы используете Sitecore, вы всегда можете использовать некоторые встроенные функции даты, чтобы получить year, month и day, не прибегая к обработке подстрок и т. Д.

<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)"/>

Я думаю, что ответ Димитра работает хорошо, но это может немного улучшить читаемость:)

0 голосов
/ 14 декабря 2011

Не могли бы вы определить строковое значение даты "одна неделя назад", а затем выполнить текстовое сравнение с помощью XPath?

count(string(event/eventDate) > $oneweekagodatestring)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...