Subject: RE: [xsl] Looping through a tree and retaining parent values From: Emmanuel Bégué <eb@xxxxxxxxxx> Date: Wed, 1 Apr 2009 16:25:22 +0200 |
Hello, This should work: <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <body> <xsl:apply-templates/> </body> </xsl:template> <xsl:template match="menuItems"> <xsl:apply-templates/> </xsl:template> <xsl:template match="menuItem"> <p id="{@label}"> <xsl:apply-templates select="ancestor-or-self::menuItem" mode="uic"/> </p> <xsl:apply-templates/> </xsl:template> <xsl:template match="menuItem" mode="uic"> <uicontrol> <xsl:value-of select="@label"/> </uicontrol> </xsl:template> What this does is, for every menuItem in the source, creates a p element, then populates it with all ancestors of the current menuItem (including itself) renamed as uicontrol and having the @label as content. Regards, EB > -----Original Message----- > From: Mark Peters [mailto:flickrmeister@xxxxxxxxx] > Sent: Wednesday, April 01, 2009 3:58 PM > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: [xsl] 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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Looping through a tree and re, Mark Peters | Thread | Re: [xsl] Looping through a tree an, Mark Peters |
[xsl] Looping through a tree and re, Mark Peters | Date | Re: [xsl] Looping through a tree an, Mark Peters |
Month |