XSLT Tip - Display a field recursively... Options
neehouse
Posted: Friday, December 22, 2006 7:50:00 PM

Rank: Umbracoholic

Joined: 7/20/2006
Posts: 1,066
Location: Charleston, West Virginia, United States
A while back, a couple of people were asking how to display a field in XSLT in a recursive manner. I recently had to call a field in a recursive manner, with a bit of logic, and thought I would share my knowledge.

Simple Recursion

To select a single field in a recursive manner is actually quite simple.

Code:

<xsl:value-of select="$currentPage/ancestor-or-self::node [string(data[@alias='field'])!=''] [position()=last()] /data[@alias='field']"/>


The trick behind this is that for each node returned with a value on the field requested, that the last one (closest parent node), is the one we want to retrieve. Thus, the last position.

Of course, if you are rotating through a set of nodes with a for-each call, you can replace the $currentPage with . or current().

Conditional Recursion

If you have a more logic based situation (simple conditions), such that one field dictates the display of the other, you can add your logic into the xslt select, expanding the Simple Recursion with additional clauses.

For instance, I have two fields that determine the display of an object on a page. One field, 'hideField', is a yes/no data type, and the other, 'Field', is a textbox multiple.

I want to display my 'Field' recursively, but only if the 'hideField' has not been set to yes (1) along the way. For that, I have to extend the selection a bit. This could also be accomplished with an if statement, but I think this manner is a bit cleaner for this example.

Code:

<xsl:value-of select="$currentPage/ancestor-or-self::node [string(data[@alias='Field'])!='' or data[@alias='hideField']=1] [position()=last()] [data[@alias='hideField']!=1] /data[@alias='Field']"/>


What this is basically doing is finding the last node (closest parent) that either has content in the Field or the hideField option is set to yes(1). If that last item does not have hideField set to yes(1)[aka, it is set to no], then the Field is displayed.

Fallback Recursion

If you want to display a secondary field if the primary is not available, but maintain the recursive approach, some fun coding must occur. It isn't as pretty, but, it gets the job done.

Code:

<xsl:value-of select="$currentPage/ancestor-or-self::node [string(data[@alias='Primary'])!='' or string(data[@alias='Secondary'])!=''] [position()=last()] [data[@alias='Primary']!=''] /data[@alias='Primary']"/>

<xsl:value-of select="$currentPage/ancestor-or-self::node [string(data[@alias='Primary'])!='' or string(data[@alias='Secondary'])!=''] [position()=last()] [data[@alias='Secondary']!='' and data[@alias='Primary']=''] /data[@alias='Secondary']"/>


What this xslt statement is doing is Looking at the Primary and Secondary fields on the node tree. If either one has a value, the node is selected, from which we take the last node (closest parent). We then test for data in the Primary field, which if it contains data, we are shown that field. The second statement does the same as the first, however, it tests for data on the Secondary field, but only if there is no data on the Primary field, as we don't want to show both fields.

Additional Thoughts

If you are trying to read content from a field that uses the Richtext Editor, you may have to apply the umbraco.library:StripHtml function into your code, as to keep you from selecting a field that has a set of paragraph tags, but no content.

While these solutions may not be an exact answer to your needs, I hope it opens up the possibilities that XSLT can do for you.

As a side note, I did not test every example here (specifically the last example), but did test the first and second examples, barring any typing errors.

Case



• 2007/2008 MVP • 2008/2009 MVP • Core Developer • Certified Professional Level I & II •
mortenbock
Posted: Wednesday, December 27, 2006 1:10:07 PM

Rank: Addict

Joined: 7/19/2006
Posts: 733
Location: Århus, Denmark
Nice how-to article :-)

thanks

I'm looking for a new job

Morten Bock - Level 2 certified - MVP 2008/2009 - My danish blog with a few english posts

neehouse
Posted: Wednesday, December 27, 2006 2:51:25 PM

Rank: Umbracoholic

Joined: 7/20/2006
Posts: 1,066
Location: Charleston, West Virginia, United States
Thank you Morton...

As time permits, and topics come available, I will try to write some additional Tips..

• 2007/2008 MVP • 2008/2009 MVP • Core Developer • Certified Professional Level I & II •
neehouse
Posted: Monday, April 30, 2007 3:32:31 AM

Rank: Umbracoholic

Joined: 7/20/2006
Posts: 1,066
Location: Charleston, West Virginia, United States
As pointed out in another post, I made a mistake in the above code. instead of [position()=last()], in should read [position()=1] or just [1].

This is due to the way that XSLT actually orders entries when using the axis ancestor-or-self (or just ancestor for that matter). When using this axis, the results are returned with the items closest to the context node listed first.

So, if you used the above anywhere, please check and correct your code.

Casey

• 2007/2008 MVP • 2008/2009 MVP • Core Developer • Certified Professional Level I & II •
bnkrazy
Posted: Thursday, July 17, 2008 3:08:23 PM
Rank: Newbie

Joined: 5/13/2008
Posts: 24
Location: VA, USA
Just wanted to say this tip was very useful! Both in terms of solving my problem and helping me learn a bit more about how xslt works. Thanks!

Chris
amritanshu
Posted: Tuesday, July 22, 2008 4:17:18 PM

Rank: Newbie

Joined: 7/2/2008
Posts: 11
Location: India
Thank you Morton... Its brilliant... thanks a ton...


Good judgment comes from experience, and often experience comes from bad judgment. So experience is simply the name we give our mistakes...
Users browsing this topic
Guest


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.