[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Looping through a tree and retaining parent values
Hi Everyone, I'm puzzling over a transformation that I thought would be simple but which becomes progressively more complex as I try to wrap my mind around it. Here is a series of menuItem nodes, which are nested in menuItems nodes. Each menuItem node has a label attribute. <menuConfig> <menu id="A"> <menuItems> <menuItem label="1"> <menuItems> <menuItem label="a"/> <menuItems> <menuItem label="1a"> <menuItems> <menuItem label="1a.a"/> <menuItem label="1a.b"/> </menuItems> </menuItem> </menuItems> <menuItem label="b"> </menuItem> </menuItems> </menuItem> <menuItem label="2"> <menuItems> <menuItem label="c"/> <menuItem label="d"> <menuItems> <menuItem label="2d"> <menuItems> <menuItem label="2d.d"/> <menuItem label="2d.e"/> <menuItem label="2d.f"/> </menuItems> </menuItem> </menuItems> </menuItem> <menuItem label="e"> <menuItems> <menuItem label="2e"> <menuItems> <menuItem label="2e.g"/> </menuItems> </menuItem> </menuItems> </menuItem> </menuItems> </menuItem> </menuItems> </menu> </menuConfig> What I'm trying to do is create a set of p nodes which nest a series of uicontrol nodes, one uicontrol node for each level of menuItem in the original XML document. In other words, for each menuItem in the original XML, there should be a uicontrol element. The first uicontrol node in the series contains the @label value for the parent menuItem node. The next uiconcontrol node in the series contains the @label value for the first child menuItem node, and so on. The p node should have an id attribute whose value is the @label value of the last child node in each tree. Here is an example: <body> <p id="1"> <uicontrol>1</uicontrol> </p> <p id="a"> <uicontrol>1</uicontrol> > <uicontrol>a</uicontrol></p> <p id="1a"> <uicontrol>1</uicontrol> > <uicontrol>a</uicontrol> > <uicontrol>1a</uicontrol> </p> <p id="1.1a"> <uicontrol>1</uicontrol> > <uicontrol>a</uicontrol> > <uicontrol>1a</uicontrol> > <uicontrol>1a.a</uicontrol> </p> <p id="1.1b"> <uicontrol>1</uicontrol> > <uicontrol>a</uicontrol> > <uicontrol>1a</uicontrol> > <uicontrol>1b.b</uicontrol> </p> <p id="b"> <uicontrol>1</uicontrol> > <uicontrol>b</uicontrol> </p> <p id="2"> <uicontrol>2</uicontrol> <p id="c"> <uicontrol>2</uicontrol> > <uicontrol>c</uicontrol> </p> <p id="d"> <uicontrol>2</uicontrol> > <uicontrol>d</uicontrol> </p> <p id="2d"> <uicontrol>2</uicontrol> > <uicontrol>d</uicontrol> > <uicontrol>2d</uicontrol> </p> <p id="2d.d"> <uicontrol>2</uicontrol> > <uicontrol>d</uicontrol> > <uicontrol>2d</uicontrol> > <uicontrol>2d.d</uicontrol> </p> <p id="2d.e"> <uicontrol>2</uicontrol> > <uicontrol>d</uicontrol> > <uicontrol>2d</uicontrol> > <uicontrol>2d.e</uicontrol> </p> <p id="e"> <uicontrol>2</uicontrol> > <uicontrol>e</uicontrol> </p> <p id="2e"> <uicontrol>2</uicontrol> > <uicontrol>e</uicontrol> > <uicontrol>2e</uicontrol></p> <p id="2e.g"> <uicontrol>2</uicontrol> > <uicontrol>e</uicontrol> > <uicontrol>2e</uicontrol> > <uicontrol>2e.g</uicontrol> </p> </body> So far, I've come up with a stylesheet that produces a single p node for every parent menuItem. It's a start. I've thought about trying to use variables to retain the menuItem/@label values at each level in the tree; but, reading about variables, I'm not sure this is possible. Likewise, I've thought about defining each loop in a separate template and then calling each template from the "master" template. But then, I'm not sure how I'd retrieve the final menuItem/@label value for the p/@id value. And I must not understand the last() function correctly. The p/@id values inserted by the stylesheet are "1a" and "2e.g," and not the @label value for the last menuItem in each tree. <xsl:template match="/"> <xsl:for-each select="//menu"> <body> <xsl:for-each select="menuItems"> <xsl:for-each select="menuItem"> <p> <xsl:attribute name="id"> <xsl:value-of select="descendant::menuItem[last()]/@label"/> </xsl:attribute> <uicontrol> <xsl:value-of select="@label"/> </uicontrol> > <xsl:for-each select="descendant::menuItem[2]"> <uicontrol> <xsl:value-of select="@label"/> </uicontrol> > <xsl:for-each select="descendant::menuItem[3]"> <uicontrol> <xsl:value-of select="@label"/> </uicontrol> > <xsl:for-each select="descendant::menuItem[4]"> <uicontrol> <xsl:value-of select="@label"/> </uicontrol> > <xsl:for-each select="descendant::menuItem[5]"> <uicontrol> <xsl:value-of select="@label"/> </uicontrol> > </xsl:for-each> </xsl:for-each> </xsl:for-each> </xsl:for-each> </p> </xsl:for-each> </xsl:for-each> </body> </xsl:for-each> </xsl:template> I'd appreciate any help you could offer. Thanks, Mark -- Mark Peters Senior Technical Writer Saba Software
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|