Subject: Re: [xsl] Creating Hierachial menu From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Wed, 17 Jul 2002 18:12:55 +0100 |
Hi Terry, > I have done simiar things in the past where one of the generated > nodes is a category and using keys() and generate-id() etc (the > Meunchian? technique I think they call it) I have created a menu > based on these categories, however this has always been a top level > menu. Now I am trying to create a multi level menu system and I > can't seem to make the logical leap using the same approach. Each > image can be in more than one category - hence the duplicate > resourceID's in the XML Interesting problem. I don't think that the Muenchian Method will help you here because you don't know the number of levels in advance, so that makes it very difficult to create the keys that you'd need to use it. Instead, I think that you need to create a recursive template that accepts a set of menus and a specified level. It should create the menu item for the first of the passed menus, giving the text of the menuItem element with the specified value for its hierLevel attribute, then work out which other menus in the list have the same value for their child menuItem element at the requisite level. Finally it should move on to those menus that have a *different* value for their relevant menuItem element child, to create menus at the same level for them. The following template does this, just creating text to get an indented output. You'll probably want to change what it creates, but hopefully this will get you part the way there. <xsl:template match="MenuRoot" name="createMenus"> <xsl:param name="menus" select="menu" /> <xsl:param name="level" select="1" /> <xsl:param name="indent" select="'
'" /> <xsl:if test="$menus"> <xsl:variable name="item" select="$menus[1]/menuItem[@hierLevel = $level]" /> <xsl:if test="$item"> <xsl:value-of select="concat($indent, $item)" /> <!-- call for the next level on those menus that share the value for their child menuItem --> <xsl:call-template name="createMenus"> <xsl:with-param name="menus" select="$menus[menuItem[@hierLevel = $level] = $item]" /> <xsl:with-param name="level" select="$level + 1" /> <xsl:with-param name="indent" select="concat($indent, ' ')" /> </xsl:call-template> <!-- call for the same level on those menus that don't share the value for their child menuItem --> <xsl:call-template name="createMenus"> <xsl:with-param name="menus" select="$menus[menuItem[@hierLevel = $level] != $item]" /> <xsl:with-param name="level" select="$level" /> <xsl:with-param name="indent" select="$indent" /> </xsl:call-template> </xsl:if> </xsl:if> </xsl:template> The biggest problem with this approach is that it involves visiting each menu element lots of times, so you may well find that for your 1000 images it takes prohibitively long. Dimitre will probably have some good ideas about how to speed it up. You implied in your message that you could generate a different XML structure. If you can, I suggest that you do -- XSLT 1.0's not very good at grouping, and it's likely that the work involved creating a structure for the XML that's easier for XSLT to deal with will end up being less overall if you do it outside XSLT. --- Interesting challenge for XSLT 2.0's grouping mechanisms here. You still need the recursive call so that you can step down the levels, but the grouping itself is a lot easier: <xsl:template match="MenuRoot" name="createMenus"> <xsl:param name="menus" select="menu" /> <xsl:param name="level" select="1" /> <xsl:param name="indent" select="'
'" /> <xsl:for-each-group select="$menus" group-by="menuItem[@hierLevel = $level]"> <xsl:value-of select="concat($indent, menuItem[@hierLevel = $level])" /> <xsl:call-template name="createMenus"> <xsl:with-param name="menus" select="current-group()" /> <xsl:with-param name="level" select="$level + 1" /> <xsl:with-param name="indent" select="concat($indent, ' ')" /> </xsl:call-template> </xsl:for-each-group> </xsl:template> Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Creating Hierachial menu, Terry Clark | Thread | RE: [xsl] Creating Hierachial menu, Brad Miller |
[xsl] ANN: free RenderX XEP for uni, David Tolpin | Date | [xsl] Translating character entitie, Bradford, Denis |
Month |