Displaying Multiple Select Fields One Per Row in a Dataview Web Part

As I’m working more and more with SharePoint Designer 2010, I’m finding that I’m developing a library of XSLT snippets that might be useful for others. This is one example. (Note, all screenshots are from SPD2010. Click the images to view a larger version.)

The Scenario

You have a list that uses another list as a look up and allows for multiple values. You want to display that list in a Data View Web Part. The out of the box behavior is to display the multiple values as a semi-colon delimited string of text. Like so:

Default Behavior - an unreadable string of text
Default Behavior – an unreadable string of text

We can make the text readable by adding a parameter to the select statement – disable-output-escaping=”yes.” That will render a functional list of links.

<xsl:value-of select="@Program_x0020_Area" disable-output-escaping="yes"/>

A Functional List of Links
A Functional List of Links

But, a semi-colon delimited list of links isn’t exactly the most user-friendly presentation.

The Solution

Thankfully, there’s a fairly simple way to fix it, though it does require diving into XSLT. I grabbed the base template from kicktech, and simply implemented it in SharePoint Designer.

In split view, find the XSLT in your page. You can put this extra template anywhere outside of the existing templates. I like to add my templates at the end of the stylesheet. So, search for </xsl:stylesheet></XSL> and paste the following right above it.

<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:when test="contains($text, $replace)">
<xsl:value-of select="substring-before($text,$replace)" />
<xsl:value-of select="$by" />
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text"
select="substring-after($text,$replace)" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
<xsl:value-of select="$text" />

Now, find the column where you are outputting your multiple select lookup. It should look something like this:
<xsl:value-of select="@YourColumnName" disable-output-escaping="yes"/>

We are going to replace that simple select with a call to our custom template. But, we need to wrap it with variable tags, so that when we’re done, we can once again disable the output escaping. Then, we’ll do a simple select on our new variable. Here’s an example of replacing the semi-colon with a line break (change “@YourColumnName” to the column you want to display):
<xsl:variable name="thisRow">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="@YourColumnName" />
<xsl:with-param name="replace" select="';'" />
<xsl:with-param name="by" select="'<br/>'" />
<xsl:value-of select="$thisRow" disable-output-escaping="yes"/>

The final result is a one-per-line list of the items selected in the multiple select column.

Final Result - One Item Per Line
Final Result – One Item Per Line

You might note that XLST has a built-in translate function that would do the same thing if you’re only wanting to replace one character with another. However, it doesn’t work to replace a single character with a set of characters.