Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old October 17th, 2006, 05:19 PM
Authorized User
 
Join Date: Jun 2003
Posts: 17
Thanks: 0
Thanked 0 Times in 0 Posts
Default Get distinct values on *second* grouping of nodes.

I'm stumped again!!!

I have stumbled upon a task that I am having trouble solving.

I have the following XML file (see below) which contains information about breakfast foods.

For my first task, I have successfully grouped a list of FOOD under their related FOOD_TYPES. (Many thank yous to Michael Kay for setting me on the right path with that one.)

Now for my second trick, I want to show that I can choose two or more FOOD TYPES, and list a distinct group of FOOD under those types.

This has got to be simple, but it is proving to be beyond me.

Immediately below is my XML file - and below that, XSL code that I am working on. My version of MSXML does not seem to understand the keyword "distinct-value", so I can't use that. I thought that if I used a "for-each" loop for each FOOD TYPE and then nested another "for-each" loop within that one -- which would use KEYS and the COUNT[] method to return only unique FOODS -- that that would work, but it doesn't.

I tried to use the "generate-id" idea but that didn't work, either.

The best I can guess is that since my first "for-each" loop is looping through each FOOD_ID found in FOOD_TYPE (which has the duplicate info...generate_id didn't work ... because it just created a unique id for something that repeated.

As for the count[] method not working in the nested "for-each" loop ... I am stumped ... I must not understand how those nodes find each other.

Basically, if I choose FOOD_TYPE where the food_type_id = 1 or food_type_id = 4, I do *NOT* want to see "Belgian Waffles" repeat itself just because it is in those two groups.

So perhaps I might need to revert to a "preceding-sibling" maneuver, but I'll admit I tried that earlier, and THAT didn't work.

Which is why I am hollering for help. HELP!!!!!

Apologies for this rudimentary post,

Susan

---------------------------------------
FOOD.XML
---------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<breakfast_menu>
    <food>
    <food_id>1</food_id>
        <name>Belgian Waffles</name>
        <price>$5.95</price>
        <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
        <calories>650</calories>
    </food>
    <food>
    <food_id>2</food_id>
        <name>Strawberry Belgian Waffles</name>
        <price>$7.95</price>
        <description>light Belgian waffles covered with strawberries and whipped cream</description>
        <calories>900</calories>
    </food>
    <food>
    <food_id>3</food_id>
        <name>Berry-Berry Belgian Waffles</name>
        <price>$8.95</price>
        <description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
        <calories>900</calories>
    </food>
    <food>
    <food_id>4</food_id>
        <name>French Toast</name>
        <price>$4.50</price>
        <description>thick slices made from our homemade sourdough bread</description>
        <calories>600</calories>
    </food>
    <food>
    <food_id>5</food_id>
        <name>Homestyle Breakfast</name>
        <price>$6.95</price>
        <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
        <calories>950</calories>
    </food>


  <food_type>
    <food_type_id>1</food_type_id>
    <food_type_name>WAFFLES</food_type_name>
    <food_id>1</food_id>
  </food_type>
  <food_type>
    <food_type_id>1</food_type_id>
    <food_type_name>WAFFLES</food_type_name>
    <food_id>2</food_id>
  </food_type>
  <food_type>
    <food_type_id>1</food_type_id>
    <food_type_name>WAFFLES</food_type_name>
    <food_id>3</food_id>
  </food_type>

  <food_type>
    <food_type_id>2</food_type_id>
    <food_type_name>FRENCH TOAST</food_type_name>
    <food_id>4</food_id>
  </food_type>

  <food_type>
    <food_type_id>3</food_type_id>
    <food_type_name>TRADITIONAL BREAKFASTS</food_type_name>
    <food_id>5</food_id>
  </food_type>

  <food_type>
    <food_type_id>4</food_type_id>
    <food_type_name>COMBO BREAKFASTS</food_type_name>
    <food_id>5</food_id>
  </food_type>
  <food_type>
    <food_type_id>4</food_type_id>
    <food_type_name>COMBO BREAKFASTS</food_type_name>
    <food_id>1</food_id>
  </food_type>

</breakfast_menu>


---------------------------------------
FOOD.XSL
---------------------------------------

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>

  <xsl:key name="food" match="food" use="food_id"/>
  <xsl:key name="foodType" match="food_type" use="food_type_id"/>

  <xsl:template match="/">
    <html>
      <body>


        <p>
          <h3>Example 1</h3>
          <b>Display a list of foods, grouped by food type</b>
            <xsl:for-each select="//food_type[count(. | key('foodType',food_type_id)[1]) = 1]">
            <p>
              <xsl:variable name="foodType" select="food_type_id"/>
              <xsl:value-of select="food_type_id"/>)
              <xsl:text> </xsl:text>
              <xsl:value-of select="food_type_name"/>

              <br></br>

              <xsl:for-each select="//food_type[food_type_id = $foodType]/food_id">
                <xsl:variable name="foodID" select="."/>
                Breakfast Name: <i><xsl:value-of select="//food[food_id=$foodID]/name"/>
                </i><br></br>
              </xsl:for-each>
            </p>
          </xsl:for-each>
        </p>

        <p>
          <h3>Example 2</h3>
          <p>
            <b>Show a unique list of Breakfast Items that belong to food types "Waffles" and "Combos".</b>
          </p>

          <xsl:for-each select="//food_type[count(. | key('foodType',food_type_id)[1]) = 1]">

              <xsl:variable name="foodType" select="food_type_id"/>
              <xsl:if test="$foodType = 1 or $foodType=4">
                [u]<xsl:value-of select="food_type_id"/>)<xsl:text> </xsl:text><xsl:value-of select="food_type_name"/>
                </u>
                <xsl:text> </xsl:text>
              </xsl:if>

          </xsl:for-each>
          <br></br>
          <!--||************************************************ **************
              || TROUBLE AREA - CAN'T GET DISTINCT FOOD IDS!!!!!
              ||************************************************ **************-->
          <xsl:for-each select="//food_type[food_type_id=1 or food_type_id=4]">
                 <xsl:sort select="food_id"/>
                 <xsl:variable name="foodType" select="food_type_id"/>
                 <xsl:variable name="foodID" select="food_id"/>

                <xsl:for-each select="//food[count(. | key('food', $foodID)[1])=1]">
                    <li><xsl:value-of select="name"/></li>
                </xsl:for-each>

          </xsl:for-each>


        </p>

      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>
__________________
Susan :)
 
Old October 17th, 2006, 05:29 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Since Joe and I are about the only people who answer questions on this list, I'll take the trouble to say that I'm not going to tackle this one. Sorry. I'm just too busy, and I just don't find solving grouping problems in XSLT 1.0 much fun: given that there are much better tools for the job in 2.0, it feels like cutting down trees with a handsaw.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old October 17th, 2006, 09:13 PM
Authorized User
 
Join Date: Jun 2003
Posts: 17
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Oh sigh. Well - alright, then - I shall take it upon myself to determine this solution. Certainly it seems like a simple enough task. Should I answer my own question - I will post the answer here!

A good challenge for a beginner. Thank you for setting me on a quest.

-- Susan
 
Old October 23rd, 2006, 10:18 AM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
Send a message via Yahoo to bonekrusher
Default

Can you use XSLT 2.0?



 
Old October 23rd, 2006, 10:34 AM
Authorized User
 
Join Date: Jun 2003
Posts: 17
Thanks: 0
Thanked 0 Times in 0 Posts
Default

No, I cannot use XSLT 2.0. We had a look at it and "the team" agreed not to use it, since it is not native in our .NET studio and we don't want to add anything new to our server.

So, basically, I am in Hell, unless I get a "eureka" moment (it isn't happening) or someone with a hefty knowledge of XSLT 1.0 (Jeni Tennison *where are youuuuuuuuuu*) comes to save my day.

I'm getting closer to a solution all the time - just can't seem to GET there. And my whole team is counting me (me!) to come up with the solution.

Ha!!

(Help. Someone. Please?)

Susan





Similar Threads
Thread Thread Starter Forum Replies Last Post
Muenchian Grouping on individual nodes in xslt1.0 sudhish.sikhamani XSLT 9 July 1st, 2008 10:32 AM
Grouping and Distinct items Condor76 XML 5 May 23rd, 2007 01:11 AM
count distinct nodes alexshiell XSLT 2 January 27th, 2005 11:19 AM
Grouping Nodes shoei78 XSLT 3 May 28th, 2004 10:34 PM
xslt 1.0 distinct grouping cassebn XSLT 3 July 30th, 2003 07:31 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.