Monday 24 May 2010

Removing whitespace from HTML tags

The Problem

This situation occurs when using the .net 2.0 classes to transform XML into HTML with a style sheet the transform (System.Xml.Xsl.XslCompiledTransform).  the output will include whitespace inside of certain HTML tags that may occasionally display within form fields when output.  This can be a pain especially when displaying TextArea elements. In IE the behaviour appeared to change unexpectedly when some other element appeared before the TextArea – such as a dropdown list (select).

The Solution

A solution is to remove the whitespaces from these tags after it has been transformed.

private string CleanUpWhitespaceInTags(string xmlString)
{
return cleanUpWhitespaceInTagsRegEx.Replace(xmlString, cleanUpWhitespaceInTagsReplacement);
}

private static readonly Regex cleanUpWhitespaceInTagsRegEx = new Regex(@"<(?<tagName>[\w-]+)\b(?<attributes>[^>]*)>\s*(?<content>[^<]*?)\s*</\1>");
private const string cleanUpWhitespaceInTagsReplacement = "<${tagName}${attributes}>${content}</${tagName}>";


The above code uses a regular expression to match tags that have no inner xml/html and gets named captures of the tag name, it’s attributes and content (without any surrounding whitespace).



To break it down:

























































< match the opening tag’s starting brace
(?<tagName>[\w-]+) capture any valid tag name (containing one or more word characters or dashes)
\b check that we are at a word boundary
(?<attributes>[^>]*) capture any characters after the tag name and before an end brace as attributes
> match the opening tag’s end brace
\s* match any whitespace on the left of the content
(?<content>[^<]*?) capture any character that isn’t a starting brace but don’t be greedy
\s* match any whitespace on the right of the content
</\1> match the closing tag


Disclaimer: Whether this regex covers all scenarios has not been tested but it works for the situation we encountered.



The replacement string then reconstitutes the tag, attributes and content without the leading or trailing whitespace.



Technorati Tags: ,,

Friday 14 May 2010

Properly disposing a System.Threading.Timer

The following test fixture shows how a timer can be properly disposed in order to ensure that the thread executing the callback has completed (or we've timed out waiting for it):

[TestClass]
public class TimerFixture
{
[TestMethod]
public void Check_timer_dispose_behaviour()
{
System.Threading.Timer timer = new System.Threading.Timer(new System.Threading.TimerCallback(OnTick), null, 100, 0);

while (!isProcessing) Thread.Sleep(50);

WaitHandle waitHandle = new AutoResetEvent(false);

timer.Dispose(waitHandle);

isStopping = true;

WaitHandle.WaitAll(new[] { waitHandle }, 1000);

Assert.IsFalse(isProcessing);
}

private void OnTick(object state)
{
isProcessing = true;

while (!isStopping) Thread.Sleep(100);

Thread.Sleep(200);

isProcessing = false;
}

private bool isStopping = false;
private bool isProcessing = false;
}