Dev Notes

Notes on Development with Microsoft Technologies

Set Limits on XSLT Recursive Functions

2 Comments

Recently, I had worked to help a client create an intranet portal and suddenly the portal started taking between 8 and 10 seconds to display the home page. All other pages in the solution were snappy and displayed very quickly. Returning to the development environment, the problem could not be reproduced and all pages continued to be displayed quickly. At first, it appeared the farm’s SQL server might be the issue so the developer dashboard was turned on to see where the bottleneck was occurring. After turning on the developer dashboard, it became very clear where the problem existed — a Content Query Web Part was taking on average about 8 seconds to render content.

The content for the CQWP originated in a standard SharePoint Publishing Pages library where the average size of the publishing page ranged between 10 – 20 KB. However, there were two items over 150 KB. Both of these pages contained a long list of hyperlinks and references to images. One of the pages was copied into the development environment and the same bottleneck began appearing — the server would respond and then wait to provide content. At this point, I remember a recursive function in XSLT that was used to decide to show a more link if the page contained more than a summary. Below is the template that was in use:

	<xsl:template name="RemoveHtml">
	    <xsl:param name="text"/>
	    <xsl:choose>
	        <xsl:when test="contains($text, '&amp;lt;')">
	            <xsl:value-of select="substring-before($text, '&amp;lt;')"/>
	            <xsl:call-template name="RemoveHtml">
	                    <xsl:with-param name="text" select="substring-after($text, '&amp;gt;')"/>
	            </xsl:call-template>
	        </xsl:when>
	        <xsl:otherwise>
	            <xsl:value-of select="$text"/>
	        </xsl:otherwise>
	    </xsl:choose>
	</xsl:template>

The basic idea behind the template is to grab the text by ignoring anything between the opening and closing of each tag. Since XSLT does not include a RegEx matching function, the only way to accomplish the goal is to recursively call the function.

The optimization of the template was actually very simple. Since the template is used to determine if one of the publishing items includes additional content and render a more link, the function was restricted to look at very small number of characters in the complete string.

	<xsl:template name="RemoveHtml">
	    <xsl:param name="text"/>
	    <xsl:variable name="length" select="string-length($text)"/>
	    <xsl:variable name="parseText">
	    <xsl:choose>
	    	<xsl:when test="$length &gt; 2000">
	    		<xsl:value-of select="substring($text,1,2000)"/>
	    	</xsl:when>
	    	<xsl:otherwise>
	    		<xsl:value-of select="$text"/>
	    	</xsl:otherwise>
	    </xsl:choose>
	    </xsl:variable>
	    <xsl:choose>
	        <xsl:when test="contains($parseText, '&lt;')">
	            <xsl:value-of select="substring-before($text, '&lt;')"/>
	            <xsl:call-template name="RemoveHtml">
	                    <xsl:with-param name="text" select="substring-after($parseText, '&gt;')"/>
	            </xsl:call-template>
	        </xsl:when>
	        <xsl:otherwise>
	            <xsl:value-of select="$parseText"/>
	        </xsl:otherwise>
	    </xsl:choose>
	</xsl:template>

After this simple change, the loading time for the portal dropped from 8 to 10 seconds to just under 2 seconds. The moral of the post: set limits on how many times a recursive function gets called.

Edit: I mention that XSLT does not include a RegEx function. However, I should qualify that XSLT 1.0 does not include a RegEx function.

Advertisements

Author: Chris Quick

I have been a developer of web based solutions since early 2001 delivering solutions to a wide array of organizations using ASP, ASP.NET and SharePoint. I was introduced to SharePoint in 2003 when the consulting firm I worked for at the time introduced it into the workplace. I began working with MOSS 2007 as soon as Microsoft released the RTM version in November 2006. The platform was implemented at the organization I worked for in 2007 and went live in March of that year. I was tasked with the administration and ongoing development of the platform. I currently work as a SharePoint Architect with Artis Consulting, developing solutions for a wide variety of business problems. The goal of this blog is to share my discoveries developing solutions with SharePoint. I welcome your comments and feedback to any post -- and I welcome suggestions for future topics.

2 thoughts on “Set Limits on XSLT Recursive Functions

  1. “Since XSLT does not include a RegEx matching function” is not exactly true – XSLT 1.0 does not have RegEx support, but XSLT 2.0 and 3.0 do. You might want to qualify that statement as “Since XSLT 1.0 does not include a RegEx matching function”. If only Microsoft would provide native support for XSLT 2.0…

    • You are correct that later versions of XSLT include RegEx support. I agree that it is a shame Microsoft never officially supported XSLT’s later version that include much more powerful capabilities. This has lead to so many crazy workarounds. Thank you for the suggestion and the qualification concerning XSLT 1.0.

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