RE: RE: RE: [xsl] Linear counting problem in nested loop.

Subject: RE: RE: RE: [xsl] Linear counting problem in nested loop.
From: cknell@xxxxxxxxxx
Date: Thu, 22 Jan 2004 13:59:28 -0500
The XSLT function generate-id() is designed for automatically creating unique identifiers for elements in XML documents. Trying to roll your own using a recursive template is an waste of brain power. Why can't you use generate-id()?

I have written more than one HTML menu system generated from XML files like the one you have shown and I have always used generate-id() to assign values to the id attributes. The only reason I can think that you would want to create predictable values for id attributes would be if you have written a client-side script that depends on a hierarchical relationship between the value of the id of a menu and the values of the id's of its component sub menus and menu items. If so, that is a weak and fragile approach and I suggest that you take another try at the scripting code using HTML DOM programming to get references to parent and child items.

If you have another reason for wanting to use the recursive template call method, please explain. Your XML structure is not appropriate for recursive template calls which rely on elements having the same name. For example consider this XML document:
<menu>
  <item>
    <item>
      <item></item>
    </item>
  </item>
</menu>

Now a recursive template that matches <item> would look like this:
<xsl:template match="item">
  <xsl:parameter name="parent-id" />
  <item id="{$parent-id +1 }">
    <xsl:apply-templates select="item">
      <xsl:with-param name="parent-id" select="$parent-id +1" />
    </xsl:apply-templates>
</xsl:template>

-- 
Charles Knell
cknell@xxxxxxxxxx - email



-----Original Message-----
From:     Govil, Anoop (Contractor) <Anoop.Govil@xxxxxxxxxxxxxxxx>
Sent:     Thu, 22 Jan 2004 13:18:49 -0500
To:       "'xsl-list@xxxxxxxxxxxxxxxxxxxxxx'" <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject:  RE: RE: [xsl] Linear counting problem in nested loop.

Hi Cknell,

Thanks for your reply. I was suggested that I used recursive templates by
using call-template and pass the new count to that each time to use the new
count. But I don't have an example of a recursive call-template.

I put together a simple call-template routine but my problem was how do I go
to next node with each recursive call to the template? I found out that I am
still at the root node. How do I traverse a tree ? I wished there was a
next() function just like there is last(), to traverse each node? Do you
have a generic example of a recursive template?

Thanks a lot.

Anoop


-----Original Message-----
From: cknell@xxxxxxxxxx [mailto:cknell@xxxxxxxxxx]
Sent: Thursday, January 22, 2004 11:52 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: RE: [xsl] Linear counting problem in nested loop.


It is a bedrock principle of XSLT that variables, once bound, cannot be
bound again. In short, you don't increment variables as you might in a loop
construct in other programming languages. You will have to find another way.
I suggest you investigate the generate-id() function.
-- 
Charles Knell
cknell@xxxxxxxxxx - email



-----Original Message-----
From:     Govil, Anoop (Contractor) <Anoop.Govil@xxxxxxxxxxxxxxxx>
Sent:     Thu, 22 Jan 2004 10:55:27 -0500
To:       "'xsl-list@xxxxxxxxxxxxxxxxxxxxxx'"
<xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject:  RE: [xsl] Linear counting problem in nested loop.

Hi Kakridge,

Actually, I don't need to count them all but need a running linear counter
that I use to give unique ids to various html elements like divs, img and
anchor tags while inside the for-each loop and inside the nested for-each
sub-loop. Also, this counter needs to be in same order,i.e., the order
should be same when inside the sub-loop and when in the main loop as I
mentioned in my original posting. Please suggest. Thanks.

Anoop

-----Original Message-----
From: kakridge@xxxxxxxxxxxxx [mailto:kakridge@xxxxxxxxxxxxx]
Sent: Thursday, January 22, 2004 10:26 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] Linear counting problem in nested loop.


Just to be clear, you cannot take the value before the iteration, like
this:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:template match="MENU">
	<xsl:variable name="total" select="count(MenuItems) +
count(*/SubMenuItems)"/>
	<xsl:value-of select="$total"/>

</xsl:template>
</xsl:stylesheet>



-----Original Message-----
From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx
[mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Govil, Anoop
(Contractor)
Sent: Thursday, January 22, 2004 9:34 AM
To: 'XSL-List@xxxxxxxxxxxxxxxxxxxxxx'
Subject: [xsl] Linear counting problem in nested loop.

Hi,
I have the following XML and want to implement such that I can have a
linear
counter increment with each iteration of the parent for-each loop and
also
the nested for-each loop. 
<?xml version="1.0"?>
<MENU>
    <MenuItems>
        <MenuLabel>Menu 1</MenuLabel>
        <SubMenuItems>
            <SubMenuLabel>Sub Menu 1</SubMenuLabel>
        </SubMenuItems>
        <SubMenuItems>
            <SubMenuLabel>Sub Menu 11</SubMenuLabel>
        </SubMenuItems>
    </MenuItems>
    <MenuItems>
        <MenuLabel>Menu 2</MenuLabel>
        <SubMenuItems>
            <SubMenuLabel>Sub Menu 2</SubMenuLabel>
        </SubMenuItems>
    </MenuItems>
</MENU>
e.g. The counter should return as: 
1 for Menu 1
2 for SubMenu 1
3 for SubMenu 11
4 for Menu 2
5 for SubMenu 2
So far, what I got is the counter breaks when it reaches the second
<MenuItems>, as it doesn't know about the subMenu from the first
MenuItems
counted 3 already... So the output of my code is something like this:
1 for Menu 1
2 for SubMenu 1
3 for SubMenu 11
2 for Menu 2
3 for SubMenu 2
Any help in fixing this will be much appreciated. Thanks a lot!

Anoop

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread