XSL Function: Group By

Topics: XSLT
Aug 17, 2011 at 9:07 PM

I have an XLS Function that I need to display records by Day of Week and also by Course.  I need this to group by day and then by course (Day in order of normal calendar and Course by breakfast lunch dinner) and loop from the first day of week to the last day of week.  Any assistance you that can point me in the right direction would be great!  Thanks

My Function Calls in the XML Data:

Course (ie: breakfast, lunch, dinner)
DayofWeek (ie: monday, tuesday)
Title
Description
Price 

 

I need to be able to group the items like this:

<DayofWeek>

<COURSE A>
<associated records>

<COURSE B>
<associated records>

<DayofWeek>

<COURSE A>
<associated records>

<COURSE B>
<associated records>

 

For Example:

Monday

 Breakfast
Green Eggs and Ham

 Lunch
Ham Sandwich
Tuna Salad 

 Dinner
Tuna
Chop Steak
Hamburger 

Tuesday

 Breakfast
Item1
Item2
Item

 Lunch
Item1
  Item2
Item3

 Dinner
  Item1
Item2
Item3

 

and so on... 

Aug 18, 2011 at 7:23 AM

Hi,

Check this discussion - http://compositec1.codeplex.com/discussions/267269 - there is a example of one of the XSLT grouping technique. Hope it will be helpful.

Aug 18, 2011 at 5:48 PM
Edited Aug 18, 2011 at 6:01 PM

Hi Inna,

Thanks for the link.  It was helpful.  I really am thankful for the help your team provides.  It make a Great CMS the Greatest.  I have just 2 questions that I have tried to figure out but am spinning my wheels:

I created 3 Global Datatypes:

  • menu.Course  (used to create the Daily Specials Dataset as a dropdown selector)
  • menu.DayofWeek (used to create the Daily Specials Dataset as a dropdown selector)
  • menu.DailySpecials

 

1) The Course and DayofWeek datasets are listed in ABC Order by default and this is how the XSLT Function is listing them.  So my groupings by DayofWeek are showing in ABC order instead of Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday and the Courses (Breakfast, Lunch, Dinner - not Breakfast, Dinner, Lunch).  How can I get the XML in the Function to order these the way I need them?  I tried to add a field to the DayofWeek dataset called "Order" to filter, without success.  I also tried (but not sure if it was right) using the <xsl:sort/>.

  • If I make the Course the Order By in the Get XML Function Call - I can get the the Courses to list in ABC order (and that seems to work as the logical order is in ABC anyway)

2) After I get the Sort the groups correctly (by Day and then Courses within eachday), how can I only show the Course once?  Right now for example:

Friday
 Lunch
 Flounder

 Dinner
 Lobster

 Dinner
 Steak

Monday 


MY FUNCTION

 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns:c1="http://c1.composite.net/StandardFunctions" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in lang f">
 
  <xsl:variable name="Specials" select="/in:inputs/in:result[@name='GetDailySpecialsXml']" />
 
  <xsl:key name="by-DoW" match="DailySpecials" use="@DayofWeek.DayofWeek" />
  <xsl:template match="/">
    <html>
      <head></head>
      <body>
        <div>
          <xsl:for-each select="$Specials/DailySpecials[generate-id(.)=generate-id(key('by-DoW',@DayofWeek.DayofWeek))]/@DayofWeek.DayofWeek">
           <xsl:sort />
            <h2>
              <xsl:value-of select="." />
            </h2>
            <ul>
              <xsl:for-each select="key('by-DoW',.)[position()&lt;5]">
               <li>
                 <xsl:value-of select="@Course.Course" /><br/>
                  <xsl:value-of select="@Title" /><br/>
                  <xsl:value-of select="@Price" />
                </li>
              </xsl:for-each>
            </ul>
          </xsl:for-each>
        </div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

 

The Output:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head/>
     <body>
         <div>
            <h2>Friday</h2>
             <ul>
                 <li>
                    Lunch
                    <br/>
                    Flounder with Crab Imperial
                    <br/>
                    $10.95
                </li>
                 <li>
                    Dinner
                    <br/>
                    Two 5oz Lobster Tails
                    <br/>
                    $21.95
                </li>
                 <li>
                    Dinner
                    <br/>
                    Buy One Regular Dinner Entrée Get the Second Half Price (4pm - 6pm)
                    <br/>
                </li>
            </ul>
            <h2>Monday</h2>
             <ul>
                 <li>
                    Lounge
                    <br/>
                    1/2 Price Burgers in the Lounge
                    <br/>
                </li>
                 <li>
                    Lunch
                    <br/>
                    Crabmelt
                    <br/>
                    $11.95
                </li>
                 <li>
                    Dinner
                    <br/>
                    Stuffed Shrimp
                    <br/>
                    $12.95
                </li>
            </ul>
            <h2>Sunday</h2>
             <ul>
                 <li>
                    Breakfast
                    <br/>
                    Sunday's Join Us for Breakfast 7:30 - 12:00
                    <br/>
                </li>
                 <li>
                    Dinner
                    <br/>
                    Complimentary Cheese & Crackers
                    <br/>
                </li>
                 <li>
                    Dinner
                    <br/>
                    Slow Oven Roasted Prime Rib
                    <br/>
                    $14.95
                </li>
            </ul>
            <h2>Thursday</h2>
             <ul>
                 <li>
                    Lunch
                    <br/>
                    Jumbo Hot Dog & Sauerkraut
                    <br/>
                    $5.95
                </li>
                 <li>
                    Dinner
                    <br/>
                    Seafood Buffet
                    <br/>
                    $18.95
                </li>
            </ul>
            <h2>Tuesday</h2>
             <ul>
                 <li>
                    Lunch
                    <br/>
                    Soup & Sandwich Buffet
                    <br/>
                    $8.95
                </li>
                 <li>
                    Dinner
                    <br/>
                    10oz Rib Eye Steak
                    <br/>
                    $14.95
                </li>
            </ul>
            <h2>Wednesday</h2>
             <ul>
                 <li>
                    Lunch
                    <br/>
                    Italian Lunchmeat Wrap
                    <br/>
                    $6.95
                </li>
                 <li>
                    Dinner
                    <br/>
                    8oz Filet Mignon Dinner
                    <br/>
                    $18.95
                </li>
            </ul>
        </div>
    </body>
</html>

 

Thanks

Aug 19, 2011 at 11:57 AM

Hi,

Try this as example (note, your DayOfWeek and Course data types should have Order field):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in lang f">
  <xsl:variable name="Specials" select="/in:inputs/in:result[@name='GetDailySpecialsXml']" />
  
  <xsl:key name="by-DoW" match="DailySpecials" use="@DayOfWeek.DayOfWeek" />
  <xsl:key name="by-Course" match="DailySpecials" use="@Course.Course" />
  
  <xsl:template match="/">
    <html>
      <head>
				<!-- markup placed here will be shown in the head section of the rendered page --></head>
      <body>
        <xsl:for-each select="$Specials/DailySpecials[generate-id(.)=generate-id(key('by-DoW',@DayOfWeek.DayOfWeek))]">
          <xsl:sort select="@DayOfWeek.Order" />
          <xsl:variable name="day" select="@DayOfWeek.DayOfWeek" />
          <h2>
            <xsl:value-of select="$day" />
          </h2>
          <xsl:for-each select="$Specials/DailySpecials[generate-id(.)=generate-id(key('by-Course',@Course.Course)[@DayOfWeek.DayOfWeek=$day])]">
            <xsl:sort select="@Course.Order" />
            <xsl:variable name="course" select="@Course.Course" />
            <h3>
              <xsl:value-of select="$course" />
            </h3>
            <ul>
              <xsl:for-each select="key('by-DoW',$day)[@Course.Course = $course]">
                <li>
                  <xsl:value-of select="@Title" />
                  <br />
                </li>
              </xsl:for-each>
            </ul>
          </xsl:for-each>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Aug 19, 2011 at 2:44 PM

Thank you so much.  Worked perfectly.