Using node-set extension function this is easy to solve. Below is the
modified stylesheet (tested with IE 7):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
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</h3>
<p>
<b>Show a unique list of Breakfast Items that belong to food
types "Waffles" and "Combos".</b>
</p>
<!-- SHOW HEADER : Waffles = 1, Combos = 4. -->
<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>
<xsl:variable name="rtf">
<xsl:for-each select="//food_type[food_type_id=1 or
food_type_id=4]">
<xsl:copy-of select="//food[food_id = current()/food_id]" />
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="msxsl:node-set($rtf)/food[count(. |
key('food', food_id)[1])=1]">
<li><xsl:value-of select="name"/></li>
</xsl:for-each>
</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
On 10/24/06, Henesy, Susan <Susan(_dot_)Henesy(_at_)xerox(_dot_)com> wrote:
Dear List,
Thank you for encouraging me to re-post my question. I'm glad there was
just a strange digest error that ate my post!!
Based on the XML file I have, I want to select two Food_Types, and spit
out a distinct list of Foods that belong to the two Food_Type_Ids. I
need to prove that multiple FOOD_IDs can belong to multiple FOOD_TYPEs -
and that I can spit out those FOOD_IDs uniquely for the FOOD_TYPE_IDs I
choose.
This seems like it would be simple, but it is proving to be beyond me.
You will understand the dilemma when you see how the two node groups are
structured - similar to data I am working with from a database here at
the office.
Immediately below is my XML file - and below that, XSL code that I am
working on. 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. However, the output I get, no
matter HOW HARD I TRY, is always:
*******************************************************************
Show a unique list of Breakfast Items that belong to food types
"Waffles" and "Combos".
1) WAFFLES 4) COMBO BREAKFASTS
1) Belgian Waffles <-- Belgian waffles appears TWICE!!!!
1) Belgian Waffles <-- Belgian waffles appears TWICE!!!!
2) Strawberry Belgian Waffles
3) Berry-Berry Belgian Waffles
5) Homestyle Breakfast
*******************************************************************
Below are my XML and XSL files. Thank you in advance for any help that
anyone can give me!!
---------------------------------------------------------------
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 1: WAFFLES -->
<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 2: FRENCH TOAST -->
<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 3: TRADITIONAL BREAKFASTS -->
<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 4: COMBO BREAKFASTS -->
<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</h3>
<p>
<b>Show a unique list of Breakfast Items that belong to food
types "Waffles" and "Combos".</b>
</p>
<!-- SHOW HEADER : Waffles = 1, Combos = 4. -->
<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>
------------------------------------------------------------------------
---
END OF POST
------------------------------------------------------------------------
--
Regards,
Mukul Gandhi
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--