Split Multi-Value Strings using XSLT

As I’m working with a client for presenting categories, I needed to build a quick and easy way to split multiple managed metadata strings into multiple hyperlinks so filters could be applied. The managed metadata is set to store multiple values — and they appear as follows:

Option 1; Option 2; Option 3;

All of the data is being presented using a Content Query Web Part that makes use of the new dynamic filtering feature of the new CQWP in SharePoint 2010. I needed a way to iterate through the available options on a single item and generate a hyperlink with the appropriate filter added to the query string.

Splitting these up really is fairly easy using a recursive template (begins on line 33, called from line 20):

<!-- CUSTOM ITEM STYLE FOR CQWP -->
  <?xml:namespace prefix = xsl />
<xsl:template mode="itemstyle" match="Row[@Style='IdeaStyle']" name="IdeaStyle">
  <DIV class=Idea>
     <DIV class=LeftContainer>
        <DIV class=Points>
           <H2><xsl:value-of select="@Point_x005F_x0020_Value"></xsl:value-of></H2>
           <H4>POINTS</H4>
        </DIV>
     </DIV>
     <DIV class=RightContainer>
        <DIV class=IdeaBody>
           <H1><xsl:value-of select="@Title"></xsl:value-of></H1>
           <DIV class=IdeaBodyContent>
              <xsl:value-of select="@Idea_x005F_x0020_Text" disable-output-escaping="yes"></xsl:value-of>
           </DIV>
           <DIV class=Tags>
              <STRONG>Filed Under: </STRONG>
                        <!-- TIME TO SPLIT UP THE METADATA FIELD -->
              <xsl:call-template name="outputLinks">
                                <!-- Aircraft contains my metadata -->
                 <xsl:with-param name="list" select="@Aircraft"></xsl:with-param>
              </xsl:call-template>
           </DIV>
        </DIV>
     </DIV>
     <DIV style="CLEAR: both"></DIV>
  </DIV>
  </xsl:template>

<!-- RECURSIVE TEMPLATE, KEEPS CALLING ITSELF
     UNTIL ALL ITEMS ARE PROCESSED -->
  <xsl:template name="outputLinks">
     <xsl:param name="list"></xsl:param>
        <!-- GET EVERYTHING IN FRONT OF THE FIRST DELIMETER -->
     <xsl:variable name="first" select="substring-before($list,';')"></xsl:variable>

        <!-- STORE ANYTHING LEFT IN ANOTHER VARIABLE -->
     <xsl:variable name="remaining" select="substring-after($list,';')"></xsl:variable>
     <A>
        <xsl:attribute name="href">
           ./IdeasFiltered.aspx?System=<xsl:value-of select="$first"></xsl:value-of>
        </xsl:attribute>
        <xsl:value-of select="$first"></xsl:value-of>
     </A>;

        <!-- CHECK TO SEE IF ANYTHING IS LEFT -->
     <xsl:if test="$remaining">
                <!-- CALL THE TEMPLATE AGAIN USING THE NEW VARIABLE
                     FOR THE PARAMETER -->
        <xsl:call-template name="outputLinks">
           <xsl:with-param name="list" select="$remaining"></xsl:with-param>
        </xsl:call-template>
     </xsl:if>
  </xsl:template>

Be careful with this because you can bring a web-front end to a halt if it gets caught in a recursive loop that never ends. You could potentially pass another parameter in to store the number of iterations and increment that each time the function is called, backing out if you reach a maximum number of iterations.

Advertisements

9 thoughts on “Split Multi-Value Strings using XSLT

  1. Thank you Chris. This piece of code saved me a lot of time trying to figure out how to parse my multiple URLs.

    Your work is very much appreciated, keep it up!

  2. Which line of the code did you concat with the semicolon? I’ve tried various ones, name=list didn’t work, select= didn’t work…. I’ve got the trailing semicolon issue and would like to resolve.

  3. Hi Chris,
    i have been tryng for some time now to create the following scenario.

    I have a dataview that i want to filter. The data source connected to the dataview has a lookup column (news type of the record). In the page i have created a multiple select control that sends multiple variables through GET method (page.aspx?news_type=3,5,6).

    What i want is in my xpath filter

    to get the $title that is binded to the news_type query string to select ANY of each values i send (for example select all news that have as type_id 3 OR 5 OR 6)….

    i was trying to find xpath query or maybe to split the variable i get and append the substring-before(@News_x0020_Type., ‘;’)= before each value and join them again in one variable and send that to the xpath query….

    I am lost though… Any help would be highly appreciated 🙂

    Thanks

    Tolis

  4. Hi there,

    The trailing semicolon in & is treated as a delimiter so if there is an ampersand in one of the returned items it will break/delimit halfway.

    e.g. if delimiting with a line break, “A;B;C&D;E” will rendered out as:

    A
    B
    C&amp
    D
    E

    …because symbols are encoded at the time of processing.

    Is there any way around this?

  5. Hi,
    Thanks a lot for this article.
    I tried your code and it is working fine except that it is leaving the word. For eg;
    value = option1;option2;option3.
    Output = option1(Hyperlink);option2(Hyperlink); ;

    The option3 is blank.

    Can you please help?

      1. I had the same thing… if the last item in your list does not have a trailing semicolon, it will not work. Concat the list param with a semicolon and you’re good. Thanks for this, Chris, it is perfect!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s