<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>out &#62;&#62; m_Conscientia; &#187; Software Engineering</title>
	<atom:link href="http://blog.hypercomplex.co.uk/index.php/category/software-engineering/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.hypercomplex.co.uk</link>
	<description>a multidimensional braindump</description>
	<lastBuildDate>Sat, 27 Aug 2011 19:16:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>fatal error C1859</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2011/08/fatal-error-c1859/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2011/08/fatal-error-c1859/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 22:14:24 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[precompiled header]]></category>
		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=1647</guid>
		<description><![CDATA[Once, a friend of mine set the welcome message on his Nokia 5110 to &#8216;fatal error&#8217;. This totally baffled the salesmen in Carphone Warehouse. I was equally baffled when I returned to an old C++ project and tried to compile it in a freshly installed Visual Studio 2008 SP1. I was greeted with a series [...]]]></description>
			<content:encoded><![CDATA[<p>Once, a friend of mine set the welcome message on his <a href="http://en.wikipedia.org/wiki/Nokia_5110">Nokia 5110</a> to &#8216;fatal error&#8217;. This totally baffled the salesmen in Carphone Warehouse.</p>
<p>I was equally baffled when I returned to an old C++ project and tried to compile it in a freshly installed Visual Studio 2008 SP1. I was greeted with a series of these errors:</p>
<blockquote><p>
fatal error C1859: &#8216;Debug\blah.pch&#8217; unexpected precompiled header error, simply rerunning the compiler might fix this problem
</p></blockquote>
<p>Not surprisingly, simply rerunning the compiler did not fix the problem. In fact, this is caused by address space layout randomization on Windows7/Server2008, as noted <a href="http://blogs.msdn.com/b/vcblog/archive/2009/11/12/visual-c-precompiled-header-errors-on-windows-7.aspx">here</a>.</p>
<p>The hotfix is available here: <a href="http://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=25785">Fix for Visual C++ 2008 SP1 compiler error C1859</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2011/08/fatal-error-c1859/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to do unit test reviews</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2011/07/how-to-do-unit-test-reviews/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2011/07/how-to-do-unit-test-reviews/#comments</comments>
		<pubDate>Fri, 08 Jul 2011 23:39:11 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=1578</guid>
		<description><![CDATA[At work we have begun to push unit testing and even TDD. Consequently code reviews now include more unit tests. Often, reviewers are very focused on product code, and neglect to review tests in detail. Letting poor quality test code slip in is a big problem. Fragile tests erode confidence in unit testing as a [...]]]></description>
			<content:encoded><![CDATA[<p>At work we have begun to push unit testing and even TDD. Consequently code reviews now include more unit tests. Often, reviewers are very focused on product code, and neglect to review tests in detail. </p>
<p>Letting poor quality test code slip in is a big problem. Fragile tests erode confidence in unit testing as a valuable exercise, and tests which are hard to maintain just slow you down when the <a href="http://dilbert.com/strips/comic/1994-09-22/">inevitable changes</a> are required.</p>
<p>When I review unit test code, I consider the following:</p>
<ul>
<li>Unit tests must favour <strong>readability</strong>. They must be compact, have a clear relationship between cause and effect, and use descriptive and meaningful phrases (<a href="http://blog.jayfields.com/2006/05/dry-code-damp-dsls.html">DAMP</a>).</li>
<li>Unit tests should <strong>assert once</strong>. There must be a clear relationship between test case method name and the assertion(s). This way, it is easy to determine the purpose of the test at a glance, and it is obvious what it means if the test fails.</li>
<li>Prefer <a href="http://xunitpatterns.com/State%20Verification.html">state verification</a> to <a href="http://xunitpatterns.com/Behavior%20Verification.html">behaviour verification</a>. If you must verify behaviour (because there is no state, or it is unreasonably difficult to test state), be very careful not to over specify expectations.</li>
<li>Unit tests must be based on the <strong>public interface</strong> of a class. Testing internals makes your tests fragile. This is related to behaviour verification, sometimes you need to verify internal interactions, but this is not the same as invoking private methods in order to test them.</li>
<li>Unit tests must not contain (or contain very little) <a href="http://xunitpatterns.com/Conditional%20Test%20Logic.html">conditional logic</a>, such as branches or loops. Conditional logic makes code harder to read.</li>
<li>Unit tests must be <strong>easy to maintain</strong>. As far as possible, <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> by applying the following techniques: use test setup/tear down methods to execute code common to all tests; implement custom verification functions or classes; use framework features like <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.collectionassert%28v=VS.100%29.aspx">CollectionAssert</a>, <a href="http://msdn.microsoft.com/en-us/library/ms132151.aspx">IEqualityComparer</a> or <a href="http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx">IComparer</a>.</li>
</ul>
<p>Further reading/viewing:</p>
<p><a href="http://xunitpatterns.com/index.html">xUnit Test Patterns</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/cc163665.aspx">Write Maintainable Unit Tests That Will Save You Time And Tears &#8211; Roy Osherove</a><br />
<a href="http://vimeo.com/19431001">How to do test reviews &#8211; Roy Osherove</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2011/07/how-to-do-unit-test-reviews/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extension method to compute standard deviation of IEnumerable&lt;TimeSpan&gt;</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2011/06/extension-method-to-compute-standard-deviation-of-ienumerabletimespan/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2011/06/extension-method-to-compute-standard-deviation-of-ienumerabletimespan/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 18:24:27 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[extension method]]></category>
		<category><![CDATA[ienumerable]]></category>
		<category><![CDATA[TimeSpan]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=1591</guid>
		<description><![CDATA[Recently, I have been writing some quick and dirty performance tests. I repeat each test scenario a few times and take an average of the execution time. In order to verify that I have a reasonably stable measurement, I wanted to also display the coefficient of variation, which is defined as the ratio of the [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I have been writing some <a href="http://blogs.msdn.com/b/ricom/archive/2010/04/26/a-few-words-about-micro-benchmarks.aspx">quick and dirty performance tests</a>. I repeat each test scenario a few times and take an average of the execution time. In order to verify that I have a reasonably stable measurement, I wanted to also display the <a href="http://en.wikipedia.org/wiki/Coefficient_of_variation">coefficient of variation</a>, which is defined as the ratio of the <a href="http://en.wikipedia.org/wiki/Standard_deviation">standard deviation</a> to the mean.</p>
<p>Given a set of TimeSpan values, I want to get the standard deviation as a TimeSpan. I implemented this based on the extension method I found <a href="http://stackoverflow.com/questions/2253874/linq-equivalent-for-standard-deviation">here</a> on StackOverflow. I implemented both sample (with <a href="http://en.wikipedia.org/wiki/Bessel%27s_correction">Bessel&#8217;s correction</a>) and population standard deviation.</p>

<div class="wp_codebox"><table><tr id="p15913"><td class="code" id="p1591code3"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">class</span> StandardDeviationExtensions
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">double</span> SampleStandardDeviation<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span> IEnumerable<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&gt;</span> values<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #6666cc; font-weight: bold;">int</span> count <span style="color: #008000;">=</span> values<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>count <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #6666cc; font-weight: bold;">double</span> average <span style="color: #008000;">=</span> values<span style="color: #008000;">.</span><span style="color: #0000FF;">Average</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #6666cc; font-weight: bold;">double</span> sumOfSquaredDifferences <span style="color: #008000;">=</span> values<span style="color: #008000;">.</span><span style="color: #0000FF;">Sum</span><span style="color: #008000;">&#40;</span>v <span style="color: #008000;">=&gt;</span> Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Pow</span><span style="color: #008000;">&#40;</span>v <span style="color: #008000;">-</span> average, <span style="color: #FF0000;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">return</span> Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Sqrt</span><span style="color: #008000;">&#40;</span>sumOfSquaredDifferences <span style="color: #008000;">/</span> <span style="color: #008000;">&#40;</span>count <span style="color: #008000;">-</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #FF0000;">0.0</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">double</span> PopulationStandardDeviation<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span> IEnumerable<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&gt;</span> values<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>values<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #6666cc; font-weight: bold;">double</span> average <span style="color: #008000;">=</span> values<span style="color: #008000;">.</span><span style="color: #0000FF;">Average</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">return</span> Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Sqrt</span><span style="color: #008000;">&#40;</span>values<span style="color: #008000;">.</span><span style="color: #0000FF;">Average</span><span style="color: #008000;">&#40;</span>v <span style="color: #008000;">=&gt;</span> Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Pow</span><span style="color: #008000;">&#40;</span>v <span style="color: #008000;">-</span> average, <span style="color: #FF0000;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #FF0000;">0.0</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> TimeSpan SampleStandardDeviation<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span> IEnumerable<span style="color: #008000;">&lt;</span>TimeSpan<span style="color: #008000;">&gt;</span> values<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> TimeSpan<span style="color: #008000;">&#40;</span>
            <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">long</span><span style="color: #008000;">&#41;</span>values
                <span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Select</span><span style="color: #008000;">&#40;</span>v <span style="color: #008000;">=&gt;</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#41;</span>v<span style="color: #008000;">.</span><span style="color: #0000FF;">Ticks</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">.</span><span style="color: #0000FF;">SampleStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> TimeSpan PopulationStandardDeviation<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span> IEnumerable<span style="color: #008000;">&lt;</span>TimeSpan<span style="color: #008000;">&gt;</span> values<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> TimeSpan<span style="color: #008000;">&#40;</span>
            <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">long</span><span style="color: #008000;">&#41;</span>values
                <span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Select</span><span style="color: #008000;">&#40;</span>v <span style="color: #008000;">=&gt;</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#41;</span>v<span style="color: #008000;">.</span><span style="color: #0000FF;">Ticks</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">.</span><span style="color: #0000FF;">PopulationStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>And here are the tests:</p>

<div class="wp_codebox"><table><tr id="p15914"><td class="code" id="p1591code4"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&#91;</span>TestClass<span style="color: #008000;">&#93;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> StandardDeviationTest
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> EmptySet <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> SingleValue <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> <span style="color: #FF0000;">1.0</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> SameValues <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> <span style="color: #FF0000;">5.0</span>, <span style="color: #FF0000;">5.0</span>, <span style="color: #FF0000;">5.0</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> ScenarioValues <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> <span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> <span style="color: #FF0000;">2.0</span>, <span style="color: #FF0000;">4.0</span>, <span style="color: #FF0000;">4.0</span>, <span style="color: #FF0000;">4.0</span>, <span style="color: #FF0000;">5.0</span>, <span style="color: #FF0000;">5.0</span>, <span style="color: #FF0000;">7.0</span>, <span style="color: #FF0000;">9.0</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">double</span> ScenarioValuesSampleDeviation <span style="color: #008000;">=</span> <span style="color: #FF0000;">2.13809</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">double</span> ScenarioValuesPopulationDeviation <span style="color: #008000;">=</span> <span style="color: #FF0000;">2.0</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SampleStandardDeviation_EmptySet_HasZeroDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0.0</span>, EmptySet<span style="color: #008000;">.</span><span style="color: #0000FF;">SampleStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SampleStandardDeviation_SingleValue_HasZeroDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0.0</span>, SingleValue<span style="color: #008000;">.</span><span style="color: #0000FF;">SampleStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SampleStandardDeviation_SetOfSameValues_HasZeroDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0.0</span>, SameValues<span style="color: #008000;">.</span><span style="color: #0000FF;">SampleStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SampleStandardDeviation_ScenarioValues_HaveExpectedDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span>ScenarioValuesSampleDeviation, Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Round</span><span style="color: #008000;">&#40;</span>ScenarioValues<span style="color: #008000;">.</span><span style="color: #0000FF;">SampleStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #FF0000;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SampleStandardDeviation_TimeSpanScenarioValues_HaveExpectedDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        var timeSpanValues <span style="color: #008000;">=</span> ScenarioValues<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Select</span><span style="color: #008000;">&#40;</span>seconds <span style="color: #008000;">=&gt;</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> TimeSpan<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0</span>, <span style="color: #FF0000;">0</span>, <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&#41;</span>seconds<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        var result <span style="color: #008000;">=</span> timeSpanValues<span style="color: #008000;">.</span><span style="color: #0000FF;">SampleStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TotalSeconds</span><span style="color: #008000;">;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span>ScenarioValuesSampleDeviation, Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Round</span><span style="color: #008000;">&#40;</span>result, <span style="color: #FF0000;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> PopulationStandardDeviation_EmptySet_HasZeroDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0.0</span>, EmptySet<span style="color: #008000;">.</span><span style="color: #0000FF;">PopulationStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> PopulationStandardDeviation_SingleValue_HasZeroDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0.0</span>, SingleValue<span style="color: #008000;">.</span><span style="color: #0000FF;">PopulationStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> PopulationStandardDeviation_SetOfSameValues_HasZeroDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0.0</span>, SameValues<span style="color: #008000;">.</span><span style="color: #0000FF;">PopulationStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> PopulationStandardDeviation_ScenarioValues_HaveExpectedDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span>ScenarioValuesPopulationDeviation, Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Round</span><span style="color: #008000;">&#40;</span>ScenarioValues<span style="color: #008000;">.</span><span style="color: #0000FF;">PopulationStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #FF0000;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> PopulationStandardDeviation_TimeSpanScenarioValues_HaveExpectedDeviation<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        var timeSpanValues <span style="color: #008000;">=</span> ScenarioValues<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Select</span><span style="color: #008000;">&#40;</span>seconds <span style="color: #008000;">=&gt;</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> TimeSpan<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0</span>, <span style="color: #FF0000;">0</span>, <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&#41;</span>seconds<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        var result <span style="color: #008000;">=</span> timeSpanValues<span style="color: #008000;">.</span><span style="color: #0000FF;">PopulationStandardDeviation</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TotalSeconds</span><span style="color: #008000;">;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span>ScenarioValuesPopulationDeviation, Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Round</span><span style="color: #008000;">&#40;</span>result, <span style="color: #FF0000;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2011/06/extension-method-to-compute-standard-deviation-of-ienumerabletimespan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming Windows Phone 7</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2010/11/programming-windows-phone-7/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2010/11/programming-windows-phone-7/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 11:45:23 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[windows phone 7]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=1580</guid>
		<description><![CDATA[Programming Windows Phone 7 by Charles Petzold is available for free here.]]></description>
			<content:encoded><![CDATA[<p>Programming Windows Phone 7 by Charles Petzold is available for <em>free</em> <a href="http://www.charlespetzold.com/phone/index.html">here</a>.</p>
<div class="wp-caption alignnone" style="width: 449px"><img alt="" src="http://www.charlespetzold.com/PetzoldTattoo.jpg" title="Petzold Tattoo" width="219" height="260" /><p class="wp-caption-text">Charles Petzold: Branded</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2010/11/programming-windows-phone-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Natural User Interface TechTalk</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2010/10/natural-user-interface-techtalk/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2010/10/natural-user-interface-techtalk/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 16:43:01 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[nui]]></category>
		<category><![CDATA[talk]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=1540</guid>
		<description><![CDATA[Bill Buxton gives a great historical perspective on user interfaces and the pace of innovation.]]></description>
			<content:encoded><![CDATA[<p><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="512" height="288"><param name="source" value="http://channel9.msdn.com/scripts/VideoPlayer.xap?v=3.1" /><param name="initParams" value="deferredLoad=true,duration=0,m=http://ecn.channel9.msdn.com/o9/ch9/1911/4dafd9dd-b996-45c4-a3cd-9e0e006b1911/MDCCTechTalkBillBuxton_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/1911/4dafd9dd-b996-45c4-a3cd-9e0e006b1911/MDCCTechTalkBillBuxton_512_ch9.jpg, postid=0" /><param name="background" value="#00FFFFFF" /><a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"><br />
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/><br />
</a><br />
</object></p>
<p>Bill Buxton gives a great historical perspective on user interfaces and the pace of innovation. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2010/10/natural-user-interface-techtalk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://ecn.channel9.msdn.com/o9/ch9/1911/4dafd9dd-b996-45c4-a3cd-9e0e006b1911/MDCCTechTalkBillBuxton_ch9.wmv" length="296949957" type="video/asf" />
		</item>
		<item>
		<title>Ballmer and Ozzie at D8</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2010/07/ballmer-and-ozzie-at-all-things-d/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2010/07/ballmer-and-ozzie-at-all-things-d/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 17:55:10 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[talk]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=1554</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><object id="wsj_fp" width="408" height="270"><param name="movie" value="http://s.wsj.net/media/swf/microPlayer.swf"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="flashvars" value="videoGUID={AEB14035-DCF3-4B93-AECF-8EE499973DBB}&#038;playerid=4001&#038;plyMediaEnabled=1&#038;configURL=http://wsj.vo.llnwd.net/o28/players/&#038;autoStart=false" base="rtmpt://wsj.fcod.llnwd.net/a1318/o28/video"name="microflashPlayer"></param><embed src="http://s.wsj.net/media/swf/microPlayer.swf" bgcolor="#FFFFFF"flashVars="videoGUID={AEB14035-DCF3-4B93-AECF-8EE499973DBB}&#038;playerid=4001&#038;plyMediaEnabled=1&#038;configURL=http://wsj.vo.llnwd.net/o28/players/&#038;autoStart=false" base="rtmpt://wsj.fcod.llnwd.net/a1318/o28/video" name="microflashPlayer" width="408" height="270" seamlesstabbing="false" type="application/x-shockwave-flash" swLiveConnect="true" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2010/07/ballmer-and-ozzie-at-all-things-d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSD Compiler Benchmark</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2010/06/ssd-compiler-benchmark/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2010/06/ssd-compiler-benchmark/#comments</comments>
		<pubDate>Sat, 05 Jun 2010 16:49:55 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Benchmark]]></category>
		<category><![CDATA[msbuild]]></category>
		<category><![CDATA[OCZ Vertex 2]]></category>
		<category><![CDATA[Raptor]]></category>
		<category><![CDATA[SSD]]></category>
		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=916</guid>
		<description><![CDATA[Anandtech has some good articles illustrating the type of performance gains you might expect using an SSD disk for everyday tasks. Using Visual Studio, and in particular, compilation, are not considered. I did a cursory inspection of the rest of the Internet, and found no decent benchmarks investigating the impact of SSDs on compile time. [...]]]></description>
			<content:encoded><![CDATA[<p>Anandtech has some good <a href="http://www.anandtech.com/show/2738">articles</a> illustrating the type of performance gains you might expect using an SSD disk for everyday tasks. Using Visual Studio, and in particular, compilation, are not considered. I did a cursory inspection of the rest of the Internet, and found no decent benchmarks investigating the impact of SSDs on compile time. So, I decided to perform my own. It&#8217;s well known that a lot of the operations performed by Visual Studio are <a href="http://weblogs.asp.net/scottgu/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx">disk bound</a>, so it seems like there is some potential.</p>
<p>I discussed this with colleagues at work, and someone suggested that compiling managed code is more CPU intensive than native. This would suggest that it might be CPU bound, rather than disk bound. I therefore decided to test both native and managed code compilation, using both a conventional hard disk drive and a solid state drive.</p>
<p><strong>Test Setup</strong></p>
<p>I used my <a href="http://valid.canardpc.com/show_oc.php?id=1086991">ageing PC</a> running Windows 7 x64 Ultimate and Visual Studio 2010 Ultimate. For each disk I did a clean install and didn&#8217;t apply any updates.</p>
<p>I ran my tests on the following:</p>
<ul>
<li>A <a href="http://en.wikipedia.org/wiki/Western_Digital_Raptor">Western Digital Raptor</a> 150gb (WD1500ADFD), a 10k RPM conventional hard disk</li>
<li>An <a href="http://www.anandtech.com/show/3681/oczs-vertex-2-special-sauce-sf1200-reviewed">OCZ Vertex 2 100gb</a> SSD</li>
</ul>
<p>I selected the following test code to compile, based on it being relatively fast and self contained (I didn&#8217;t want to spend hours doing this!), and be fairly representative of a small system (compiling multiple dependent binaries):</p>
<ul>
<li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=bcb166f7-dd16-448b-a152-9845760d9b4c&#038;displaylang=en">Microsoft Enterprise Library 5.0</a> &#8211; a small set of managed components written by the Microsoft Patterns &#038; Practices team.</li>
<li><a href="http://lame.sourceforge.net/">LAME</a>, the open source MP3 encoding library. I used version 3.98.4, and did a little hacking to get it to build against a recent GTK+.</li>
</ul>
<p><strong>Results</strong></p>
<p>I compiled each test program three times and took the average result. I turned on build timing in Visual Studio by going to Tools->Options->Projects and Solutions->Build and Run->MSBuild project build output verbosity=Detailed. VS2010 now uses MSBuild for native code.</p>
<div id="attachment_931" class="wp-caption aligncenter" style="width: 500px"><a href="http://blog.hypercomplex.co.uk/wp-content/uploads/2010/06/compile-time.png"><img src="http://blog.hypercomplex.co.uk/wp-content/uploads/2010/06/compile-time.png" alt="" title="compile time" width="490" height="294" class="size-full wp-image-931" /></a><p class="wp-caption-text">Compile time in seconds. Lower is better.</p></div>
<p>So, using an SSD we get around a 21% gain in speed on native code, and a 16% gain compiling managed. Not bad. Although my Raptor isn&#8217;t the most recent model, it is representative of the fastest conventional SATA hard disk available. On this basis, I would expect a RAID setup based on 10k RPM disks to outperform the SSD.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2010/06/ssd-compiler-benchmark/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>P/Invoke Interop Assistant</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2010/05/pinvoke-interop-assistant/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2010/05/pinvoke-interop-assistant/#comments</comments>
		<pubDate>Sat, 08 May 2010 23:45:28 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[interop]]></category>
		<category><![CDATA[p/invoke]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=900</guid>
		<description><![CDATA[After messing about for hours trying to p/invoke GetTokenInformation only for it to return what appeared to be sinographs, I came accross the P/Invoke interop assistant on CodePlex. Although this didn&#8217;t solve the my problem (which was correctly marshalling a fixed size char array), it would doubtlessly have saved me time writing the boiler plate [...]]]></description>
			<content:encoded><![CDATA[<p>After messing about for hours trying to p/invoke <a href="http://msdn.microsoft.com/en-us/library/aa446671%28VS.85%29.aspx">GetTokenInformation</a> only for it to return what appeared to be sinographs, I came accross the <a href="http://clrinterop.codeplex.com/releases/view/14120">P/Invoke interop assistant</a> on CodePlex.</p>
<div id="attachment_901" class="wp-caption aligncenter" style="width: 460px"><a href="http://blog.hypercomplex.co.uk/wp-content/uploads/2010/05/pinvoke.jpg"><img src="http://blog.hypercomplex.co.uk/wp-content/uploads/2010/05/pinvoke.jpg" alt="" title="pinvoke assistant" width="450" height="258" class="size-medium wp-image-901" /></a><p class="wp-caption-text">The P/Invoke Interop Assistant: it generates some useful stuff</p></div>
<p>Although this didn&#8217;t solve the my problem (which was correctly marshalling a fixed size char array), it would doubtlessly have saved me time writing the boiler plate structs, enums and method signatures. Highly recommended.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2010/05/pinvoke-interop-assistant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parsing HTML tables into System.Data.DataTable</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2010/05/parsing-html-tables-into-system-data-datatable/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2010/05/parsing-html-tables-into-system-data-datatable/#comments</comments>
		<pubDate>Thu, 06 May 2010 20:50:08 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DataSet]]></category>
		<category><![CDATA[DataTable]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[RegEx]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=877</guid>
		<description><![CDATA[What follows is a quick and dirty class I made to parse HTML tables into DataTables. As usual, it is the result of internet search/run/bug fix/refactor. In use, it looks little like this: WebClient client = new WebClient&#40;&#41;; string html = client.DownloadString&#40;@&#34;http://www.table.co.uk&#34;&#41;; DataSet dataSet = HtmlTableParser.Parse&#40;html&#41;; Here is the implementation. It&#8217;s not optimised for runtime [...]]]></description>
			<content:encoded><![CDATA[<p>What follows is a quick and dirty class I made to parse HTML tables into <a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx">DataTable</a>s. As usual, it is the result of internet search/run/bug fix/refactor.</p>
<p>In use, it looks little like this:</p>

<div class="wp_codebox"><table><tr id="p87710"><td class="code" id="p877code10"><pre class="csharp" style="font-family:monospace;">WebClient client <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> WebClient<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #6666cc; font-weight: bold;">string</span> html <span style="color: #008000;">=</span> client<span style="color: #008000;">.</span><span style="color: #0000FF;">DownloadString</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">@&quot;http://www.table.co.uk&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
DataSet dataSet <span style="color: #008000;">=</span> HtmlTableParser<span style="color: #008000;">.</span><span style="color: #0000FF;">Parse</span><span style="color: #008000;">&#40;</span>html<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Here is the implementation. It&#8217;s not optimised for runtime performance, but it works.</p>

<div class="wp_codebox"><table><tr id="p87711"><td class="code" id="p877code11"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
<span style="color: #008080; font-style: italic;">/// HtmlTableParser parses the contents of an html string into a System.Data DataSet or DataTable.</span>
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> HtmlTableParser
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> RegexOptions ExpressionOptions <span style="color: #008000;">=</span> RegexOptions<span style="color: #008000;">.</span><span style="color: #0000FF;">Singleline</span> <span style="color: #008000;">|</span> RegexOptions<span style="color: #008000;">.</span><span style="color: #0000FF;">Multiline</span> <span style="color: #008000;">|</span> RegexOptions<span style="color: #008000;">.</span><span style="color: #0000FF;">IgnoreCase</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> CommentPattern <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;!--(.*?)--&gt;&quot;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> TablePattern <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;table[^&gt;]*&gt;(.*?)&lt;/table&gt;&quot;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> HeaderPattern <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;th[^&gt;]*&gt;(.*?)&lt;/th&gt;&quot;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> RowPattern <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;tr[^&gt;]*&gt;(.*?)&lt;/tr&gt;&quot;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> CellPattern <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;td[^&gt;]*&gt;(.*?)&lt;/td&gt;&quot;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Given an HTML string containing n table tables, parse them into a DataSet containing n DataTables.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;html&quot;&gt;An HTML string containing n HTML tables&lt;/param&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;returns&gt;A DataSet containing a DataTable for each HTML table in the input HTML&lt;/returns&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> DataSet ParseDataSet<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> html<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        DataSet dataSet <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> DataSet<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        MatchCollection tableMatches <span style="color: #008000;">=</span> Regex<span style="color: #008000;">.</span><span style="color: #0000FF;">Matches</span><span style="color: #008000;">&#40;</span>
            WithoutComments<span style="color: #008000;">&#40;</span>html<span style="color: #008000;">&#41;</span>,
            TablePattern,
            ExpressionOptions<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>Match tableMatch <span style="color: #0600FF; font-weight: bold;">in</span> tableMatches<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            dataSet<span style="color: #008000;">.</span><span style="color: #0000FF;">Tables</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>ParseTable<span style="color: #008000;">&#40;</span>tableMatch<span style="color: #008000;">.</span><span style="color: #0000FF;">Value</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">return</span> dataSet<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Given an HTML string containing a single table, parse that table to form a DataTable.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;tableHtml&quot;&gt;An HTML string containing a single HTML table&lt;/param&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;returns&gt;A DataTable which matches the input HTML table&lt;/returns&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> DataTable ParseTable<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> tableHtml<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #6666cc; font-weight: bold;">string</span> tableHtmlWithoutComments <span style="color: #008000;">=</span> WithoutComments<span style="color: #008000;">&#40;</span>tableHtml<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        DataTable dataTable <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> DataTable<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        MatchCollection rowMatches <span style="color: #008000;">=</span> Regex<span style="color: #008000;">.</span><span style="color: #0000FF;">Matches</span><span style="color: #008000;">&#40;</span>
            tableHtmlWithoutComments,
            RowPattern,
            ExpressionOptions<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        dataTable<span style="color: #008000;">.</span><span style="color: #0000FF;">Columns</span><span style="color: #008000;">.</span><span style="color: #0000FF;">AddRange</span><span style="color: #008000;">&#40;</span>tableHtmlWithoutComments<span style="color: #008000;">.</span><span style="color: #0000FF;">Contains</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;&lt;th&quot;</span><span style="color: #008000;">&#41;</span>
                                       <span style="color: #008000;">?</span> ParseColumns<span style="color: #008000;">&#40;</span>tableHtml<span style="color: #008000;">&#41;</span>
                                       <span style="color: #008000;">:</span> GenerateColumns<span style="color: #008000;">&#40;</span>rowMatches<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        ParseRows<span style="color: #008000;">&#40;</span>rowMatches, dataTable<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">return</span> dataTable<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Strip comments from an HTML stirng</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;html&quot;&gt;An HTML string potentially containing comments&lt;/param&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;returns&gt;The input HTML string with comments removed&lt;/returns&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">string</span> WithoutComments<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> html<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> Regex<span style="color: #008000;">.</span><span style="color: #0000FF;">Replace</span><span style="color: #008000;">&#40;</span>html, CommentPattern, <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Empty</span>, ExpressionOptions<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Add a row to the input DataTable for each row match in the input MatchCollection</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;rowMatches&quot;&gt;A collection of all the rows to add to the DataTable&lt;/param&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;dataTable&quot;&gt;The DataTable to which we add rows&lt;/param&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> ParseRows<span style="color: #008000;">&#40;</span>MatchCollection rowMatches, DataTable dataTable<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>Match rowMatch <span style="color: #0600FF; font-weight: bold;">in</span> rowMatches<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #008080; font-style: italic;">// if the row contains header tags don't use it - it is a header not a row</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>rowMatch<span style="color: #008000;">.</span><span style="color: #0000FF;">Value</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Contains</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;&lt;th&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                DataRow dataRow <span style="color: #008000;">=</span> dataTable<span style="color: #008000;">.</span><span style="color: #0000FF;">NewRow</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                MatchCollection cellMatches <span style="color: #008000;">=</span> Regex<span style="color: #008000;">.</span><span style="color: #0000FF;">Matches</span><span style="color: #008000;">&#40;</span>
                    rowMatch<span style="color: #008000;">.</span><span style="color: #0000FF;">Value</span>,
                    CellPattern,
                    ExpressionOptions<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> columnIndex <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> columnIndex <span style="color: #008000;">&lt;</span> cellMatches<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span> columnIndex<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    dataRow<span style="color: #008000;">&#91;</span>columnIndex<span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> cellMatches<span style="color: #008000;">&#91;</span>columnIndex<span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Groups</span><span style="color: #008000;">&#91;</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
&nbsp;
                dataTable<span style="color: #008000;">.</span><span style="color: #0000FF;">Rows</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>dataRow<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Given a string containing an HTML table, parse the header cells to create a set of DataColumns</span>
    <span style="color: #008080; font-style: italic;">/// which define the columns in a DataTable.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;tableHtml&quot;&gt;An HTML string containing a single HTML table&lt;/param&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;returns&gt;A set of DataColumns based on the HTML table header cells&lt;/returns&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> DataColumn<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> ParseColumns<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> tableHtml<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        MatchCollection headerMatches <span style="color: #008000;">=</span> Regex<span style="color: #008000;">.</span><span style="color: #0000FF;">Matches</span><span style="color: #008000;">&#40;</span>
            tableHtml,
            HeaderPattern,
            ExpressionOptions<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">from</span> Match headerMatch <span style="color: #0600FF; font-weight: bold;">in</span> headerMatches
                <span style="color: #0600FF; font-weight: bold;">select</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> DataColumn<span style="color: #008000;">&#40;</span>headerMatch<span style="color: #008000;">.</span><span style="color: #0000FF;">Groups</span><span style="color: #008000;">&#91;</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToArray</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// For tables which do not specify header cells we must generate DataColumns based on the number</span>
    <span style="color: #008080; font-style: italic;">/// of cells in a row (we assume all rows have the same number of cells).</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;rowMatches&quot;&gt;A collection of all the rows in the HTML table we wish to generate columns for&lt;/param&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;returns&gt;A set of DataColumns based on the number of celss in the first row of the input HTML table&lt;/returns&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> DataColumn<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> GenerateColumns<span style="color: #008000;">&#40;</span>MatchCollection rowMatches<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #6666cc; font-weight: bold;">int</span> columnCount <span style="color: #008000;">=</span> Regex<span style="color: #008000;">.</span><span style="color: #0000FF;">Matches</span><span style="color: #008000;">&#40;</span>
            rowMatches<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,
            CellPattern,
            ExpressionOptions<span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">from</span> index <span style="color: #0600FF; font-weight: bold;">in</span> Enumerable<span style="color: #008000;">.</span><span style="color: #0000FF;">Range</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0</span>, columnCount<span style="color: #008000;">&#41;</span>
                <span style="color: #0600FF; font-weight: bold;">select</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> DataColumn<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Column &quot;</span> <span style="color: #008000;">+</span> Convert<span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span>index<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToArray</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>As always, here are the tests. They yield 100% coverage but I still need to add some asserts on the column names.</p>

<div class="wp_codebox"><table><tr id="p87712"><td class="code" id="p877code12"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
<span style="color: #008080; font-style: italic;">/// Tests for the HtmlTableParser class</span>
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
<span style="color: #008000;">&#91;</span>TestClass<span style="color: #008000;">&#93;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> ParserTest
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> TestContext testContextInstance<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Verify that HtmlTableParser can parse an HTML file containing a single table. The</span>
    <span style="color: #008080; font-style: italic;">/// test file includes a commented out table which should be ignored. Note some tags use</span>
    <span style="color: #008080; font-style: italic;">/// attributes (we test we can parse tags with and without attributes).</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #008000;">&#91;</span>DeploymentItem<span style="color: #008000;">&#40;</span><span style="color: #666666;">@&quot;data\singleTable.txt&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> TestParseSingleTable<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #6666cc; font-weight: bold;">string</span> html <span style="color: #008000;">=</span> File<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadAllText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;singleTable.txt&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        DataTable table <span style="color: #008000;">=</span> HtmlTableParser<span style="color: #008000;">.</span><span style="color: #0000FF;">ParseTable</span><span style="color: #008000;">&#40;</span>html<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        AssertTable<span style="color: #008000;">&#40;</span>GetExpectedData<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, table<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Verify that HtmlTableParser can parse an HTML file containing multiple tables. The</span>
    <span style="color: #008080; font-style: italic;">/// test file includes a commented out table which should be ignored. The test file</span>
    <span style="color: #008080; font-style: italic;">/// contains tables both with and without headers.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
    <span style="color: #008000;">&#91;</span>DeploymentItem<span style="color: #008000;">&#40;</span><span style="color: #666666;">@&quot;data\multipleTables.txt&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#93;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> TestParseMultipleTables<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #6666cc; font-weight: bold;">string</span> html <span style="color: #008000;">=</span> File<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadAllText</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;multipleTables.txt&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        DataSet dataSet <span style="color: #008000;">=</span> HtmlTableParser<span style="color: #008000;">.</span><span style="color: #0000FF;">ParseDataSet</span><span style="color: #008000;">&#40;</span>html<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">3</span>, dataSet<span style="color: #008000;">.</span><span style="color: #0000FF;">Tables</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        var expected <span style="color: #008000;">=</span> GetExpectedData<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>DataTable table <span style="color: #0600FF; font-weight: bold;">in</span> dataSet<span style="color: #008000;">.</span><span style="color: #0000FF;">Tables</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            AssertTable<span style="color: #008000;">&#40;</span>expected, table<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> GetExpectedData<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span>
        <span style="color: #008000;">&#123;</span>
            <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">&quot;row 1, cell 1&quot;</span>, <span style="color: #666666;">&quot;row 1, cell 2&quot;</span> <span style="color: #008000;">&#125;</span>,
            <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">&quot;row 2, cell 1&quot;</span>, <span style="color: #666666;">&quot;row 2, cell 2&quot;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> AssertTable<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> expected, DataTable table<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span>expected<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, table<span style="color: #008000;">.</span><span style="color: #0000FF;">Rows</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span>, <span style="color: #666666;">&quot;Table did not contain the expected number of rows&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> expected<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> j <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> j <span style="color: #008000;">&lt;</span> expected<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span> j<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #6666cc; font-weight: bold;">string</span> actualElement <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>table<span style="color: #008000;">.</span><span style="color: #0000FF;">Rows</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>j<span style="color: #008000;">&#93;</span> <span style="color: #0600FF; font-weight: bold;">as</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Trim</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #6666cc; font-weight: bold;">string</span> expectedElement <span style="color: #008000;">=</span> expected<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>j<span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
                Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>expectedElement, actualElement, <span style="color: #666666;">&quot;Table did not contain the expected element&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>These are the test files, which are just some basic HMTL.</p>

<div class="wp_codebox"><table><tr id="p87713"><td class="code" id="p877code13"><pre class="html" style="font-family:monospace;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
      &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot; /&gt;
    &lt;meta name=&quot;robots&quot; content=&quot;all&quot; /&gt;
      &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&nbsp;
&lt;body&gt;
      &lt;!-- This table is commented out, so it shouldn't be parsed.
      &lt;table border=&quot;1&quot;&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;th&gt;Commented Heading 1&lt;/th&gt;
                  &lt;th&gt;Commented Heading 2&lt;/th&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;Commented row 1, cell 1&lt;/td&gt;
                  &lt;td&gt;Commented row 1, cell 2&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;Commented row 2, cell 1&lt;/td&gt;
                  &lt;td&gt;Commented row 2, cell 2&lt;/td&gt;
            &lt;/tr&gt;
      &lt;/table&gt;
      --&gt;
&nbsp;
      &lt;!-- The parser should ignore the border attributes --&gt;
      &lt;table border=&quot;1&quot;&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;th&gt;Heading 1&lt;/th&gt;
                  &lt;th&gt;Heading 2&lt;/th&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                  &lt;td border=&quot;1&quot;&gt;row 1, cell 1&lt;/td&gt;
                  &lt;td&gt;row 1, cell 2&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;row 2, cell 1&lt;/td&gt;
                  &lt;td&gt;row 2, cell 2&lt;/td&gt;
            &lt;/tr&gt;
      &lt;/table&gt; 
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p87714"><td class="code" id="p877code14"><pre class="html" style="font-family:monospace;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
      &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot; /&gt;
    &lt;meta name=&quot;robots&quot; content=&quot;all&quot; /&gt;
      &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&nbsp;
&lt;body&gt;
      &lt;!-- The parser should ignore the border attributes --&gt;
      &lt;table border=&quot;1&quot;&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;row 1, cell 1&lt;/td&gt;
                  &lt;td&gt;row 1, cell 2&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;row 2, cell 1&lt;/td&gt;
                  &lt;td&gt;row 2, cell 2&lt;/td&gt;
            &lt;/tr&gt;
      &lt;/table&gt; 
      &lt;!-- This table is commented out, so it shouldn't be parsed.
      &lt;table border=&quot;1&quot;&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;th&gt;Commented Heading 1&lt;/th&gt;
                  &lt;th&gt;Commented Heading 2&lt;/th&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;Commented row 1, cell 1&lt;/td&gt;
                  &lt;td&gt;Commented row 1, cell 2&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;Commented row 2, cell 1&lt;/td&gt;
                  &lt;td&gt;Commented row 2, cell 2&lt;/td&gt;
            &lt;/tr&gt;
      &lt;/table&gt;
      --&gt;
      &lt;table border=&quot;1&quot;&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;th&gt;Heading 1&lt;/th&gt;
                  &lt;th&gt;Heading 2&lt;/th&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;row 1, cell 1&lt;/td&gt;
                  &lt;td&gt;row 1, cell 2&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;row 2, cell 1&lt;/td&gt;
                  &lt;td&gt;row 2, cell 2&lt;/td&gt;
            &lt;/tr&gt;
      &lt;/table&gt; 
      &lt;table&gt;
            &lt;tr&gt;
                  &lt;td&gt;row 1, cell 1&lt;/td&gt;
                  &lt;td&gt;row 1, cell 2&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr  border=&quot;1&quot;&gt;
                  &lt;td&gt;row 2, cell 1&lt;/td&gt;
                  &lt;td border=&quot;1&quot;&gt;row 2, cell 2&lt;/td&gt;
            &lt;/tr&gt;
      &lt;/table&gt; 
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2010/05/parsing-html-tables-into-system-data-datatable/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Filtering sqlmetal output using XSLT</title>
		<link>http://blog.hypercomplex.co.uk/index.php/2010/03/filtering-sqlmetal-output-using-xslt/</link>
		<comments>http://blog.hypercomplex.co.uk/index.php/2010/03/filtering-sqlmetal-output-using-xslt/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 21:50:41 +0000</pubDate>
		<dc:creator>Alex Peck</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[build target]]></category>
		<category><![CDATA[linq]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sqlmetal]]></category>
		<category><![CDATA[visual studio]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xslt]]></category>

		<guid isPermaLink="false">http://blog.hypercomplex.co.uk/?p=799</guid>
		<description><![CDATA[I needed to generate LINQ to SQL O/RM classes for a subset of the objects in a large database. Unfortunately, sqlmetal doesn&#8217;t provide a mechanism to filter it&#8217;s output, so I made my own using XSLT, a batch file and a custom build target. This post explains how. Overview When you invoke a build, a [...]]]></description>
			<content:encoded><![CDATA[<p>I needed to generate <a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx">LINQ to SQL</a> O/RM classes for a subset of the objects in a large database. Unfortunately, <a href="http://msdn.microsoft.com/en-us/library/bb386987.aspx">sqlmetal</a> doesn&#8217;t provide a mechanism to filter it&#8217;s output, so I made my own using XSLT, a batch file and a custom build target. This post explains how. </p>
<p>
<strong>Overview</strong></p>
<p>When you invoke a build, a custom &#8220;BeforeBuild&#8221; build target runs to do the code generation. This code generation is driven by a batch file, this is what it does:</p>
<ol>
<li> Run sqlmetal to output a dbml file for the entire database schema</li>
<li> Using an XML configuration file and an XSLT transform, generate a test .cs file containing a reference to each expected table. When included in our project, this gives us a compile time test that we generated the expected classes (we make this internal).</li>
<li> Run a second XSLT transform based on the configuration file and the output a dbml file from step 1. In this step we prune the xml according to the config file. The result is a dbml file containing only the tables we specify in our configuration.</li>
<li> Run sqlmetal again using the result of step 3 as input. This time sqlmetal outputs our CSharp code for our Linq to Sql classes. </li>
</ol>
<p>The XSLT transforms are run from the command line using MSXSL.exe, which is available <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2FB55371-C94E-4373-B0E9-DB4816552E41&#038;displaylang=en">here</a>.</p>
<p>The generated CSharp files are part of my Visual Studio project. After the BeforeBuild target is run (which does the code generation), the generated code is compiled into an Assembly.</p>
<p>
<strong>Custom build target</strong></p>
<p>These are the pertinent parts of my project file. You can see that inside my project directory, I created a directory called Prebuild where the work happens. This is where the Configuration.xml, DbmlPruner.xslt, GenerateTestTypes.xslt and generate.bat files live.</p>

<div class="wp_codebox"><table><tr id="p79920"><td class="code" id="p799code20"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Project</span> <span style="color: #000066;">ToolsVersion</span>=<span style="color: #ff0000;">&quot;3.5&quot;</span> <span style="color: #000066;">DefaultTargets</span>=<span style="color: #ff0000;">&quot;Build&quot;</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #808080; font-style: italic;">&lt;!-- most of the project file omitted for brevity --&gt;</span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Target</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;BeforeBuild&quot;</span> <span style="color: #000066;">DependsOnTargets</span>=<span style="color: #ff0000;">&quot;GenerateDbClasses;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Target</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;GenerateDbClasses&quot;</span> <span style="color: #000066;">Inputs</span>=<span style="color: #ff0000;">&quot;Prebuild\Configuration.xml;Prebuild\DbmlPruner.xslt;Prebuild\GenerateTestTypes.xslt&quot;</span> <span style="color: #000066;">Outputs</span>=<span style="color: #ff0000;">&quot;MasterDb.Generated.cs;TestMasterDbTypes.cs&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Exec</span> <span style="color: #000066;">Command</span>=<span style="color: #ff0000;">&quot;$(ProjectDir)Prebuild\generate.bat $(ProjectDir) $(TargetName) master.dbml prunedmaster.dbml TestMasterDbTypes.cs MasterDb Configuration.xml master&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Project<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>
<strong>Configuration.xml</strong></p>

<div class="wp_codebox"><table><tr id="p79921"><td class="code" id="p799code21"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #808080; font-style: italic;">&lt;!-- This configuration is used to specify which tables should generate linq to SQL classes, </span>
<span style="color: #808080; font-style: italic;">  and to generate a sanity check class which verifies all the expected types exist in the </span>
<span style="color: #808080; font-style: italic;">  generated code.</span>
<span style="color: #808080; font-style: italic;">  --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Configuration</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Master Tables&quot;</span> <span style="color: #000066;">SourceXml</span>=<span style="color: #ff0000;">&quot;master.dbml&quot;</span> <span style="color: #000066;">Namespace</span>=<span style="color: #ff0000;">&quot;Master.Data.Linq&quot;</span> <span style="color: #000066;">TestClassName</span>=<span style="color: #ff0000;">&quot;TestMasterTypes&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Table</span> <span style="color: #000066;">SqlName</span>=<span style="color: #ff0000;">&quot;dbo.TestTable&quot;</span> <span style="color: #000066;">DataContextPropertyName</span>=<span style="color: #ff0000;">&quot;TestTable&quot;</span> <span style="color: #000066;">ClassName</span>=<span style="color: #ff0000;">&quot;TestTableRow&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>
<strong>GenerateTestTypes.xslt</strong></p>

<div class="wp_codebox"><table><tr id="p79922"><td class="code" id="p799code22"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #808080; font-style: italic;">&lt;!-- ===========================================================</span>
<span style="color: #808080; font-style: italic;">  Generate a C# class with members corresponding to all the linq</span>
<span style="color: #808080; font-style: italic;">  to SQL tables specified in the input file.</span>
<span style="color: #808080; font-style: italic;">================================================================ --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:stylesheet</span> <span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:output</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
//-----------------------------------------------------------------------
// <span style="color: #339933;">&lt;![CDATA[&lt;auto-generated&gt;]]&gt;</span>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost 
//     if the code is regenerated.
// <span style="color: #339933;">&lt;![CDATA[&lt;/auto-generated&gt;]]&gt;</span>
//-----------------------------------------------------------------------
&nbsp;
// Disable warning CS0169: The private field 'foo' is never used. This is 
// by design.
#pragma warning disable 0169
&nbsp;
namespace <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;/Configuration/@Namespace&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
{
    /// <span style="color: #339933;">&lt;![CDATA[&lt;summary&gt;]]&gt;</span>
    /// This class is provided as a compile time test for the linq to SQL
    /// classes specified in Prebuild/configuration.xml. It will fail to
    /// compile if one of the dependent classes is not generated (or not
    /// generated with the expected name). This is by design.
    /// <span style="color: #339933;">&lt;![CDATA[&lt;/summary&gt;]]&gt;</span>
    internal class <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;/Configuration/@TestClassName&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    {      
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:for-each</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;/Configuration/Table&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><span style="color: #ddbb00;">&amp;#9;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><span style="color: #ddbb00;">&amp;#9;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>private <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@ClassName&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span> <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;' '&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span> <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;concat(@ClassName, 'Member')&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><span style="color: #ddbb00;">&amp;#xa;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/xsl:for-each<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><span style="color: #ddbb00;">&amp;#9;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>}
}
&nbsp;
#pragma warning restore 0169
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:stylesheet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>
<strong>DbmlPruner.xslt</strong></p>

<div class="wp_codebox"><table><tr id="p79923"><td class="code" id="p799code23"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #808080; font-style: italic;">&lt;!-- ===========================================================</span>
<span style="color: #808080; font-style: italic;">  Replicate a .dbml file based on the tables specified in a </span>
<span style="color: #808080; font-style: italic;">  configuration.</span>
<span style="color: #808080; font-style: italic;">================================================================ --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:stylesheet</span> <span style="color: #000066;">xmlns:xsl</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/XSL/Transform&quot;</span></span>
<span style="color: #009900;">	 <span style="color: #000066;">xmlns:sql</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/linqtosql/dbml/2007&quot;</span></span>
<span style="color: #009900;">     <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
  	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:output</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;xml&quot;</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span> <span style="color: #000066;">indent</span>=<span style="color: #ff0000;">&quot;yes&quot;</span></span>
<span style="color: #009900;">  	  omit-xml-declaration = <span style="color: #ff0000;">&quot;no&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:template</span> <span style="color: #000066;">match</span>=<span style="color: #ff0000;">&quot;Configuration&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- load sql metal output as $database --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;database&quot;</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;document(@SourceXml)&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;namespace&quot;</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;namespace-uri($database/sql:Database)&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:comment<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> =====================================================================================
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@Name&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span> generated from database <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;$database/sql:Database/@Name&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span> (<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@SourceXml&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>)
========================================================================================== <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:comment<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- Output a tree which replicates @SourceXml but contains only the table nodes in the configuration --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Database&quot;</span> <span style="color: #000066;">namespace</span>=<span style="color: #ff0000;">&quot;{$namespace}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Name&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;$database/sql:Database/@Name&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:for-each</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;/Configuration/Table&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:variable</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;sqlName&quot;</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@SqlName&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
				<span style="color: #808080; font-style: italic;">&lt;!-- only output a table element when the source table exists --&gt;</span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:if</span> <span style="color: #000066;">test</span>=<span style="color: #ff0000;">&quot;$database/sql:Database/sql:Table[@Name=$sqlName]&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
					<span style="color: #808080; font-style: italic;">&lt;!-- Output the table substituting Member and Type for the ClassName in the configuration --&gt;</span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Table&quot;</span> <span style="color: #000066;">namespace</span>=<span style="color: #ff0000;">&quot;{$namespace}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
						<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Name&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
							<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@SqlName&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
						<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
						<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Member&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
							<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@DataContextPropertyName&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
						<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
						<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Type&quot;</span> <span style="color: #000066;">namespace</span>=<span style="color: #ff0000;">&quot;{$namespace}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
							<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Name&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
								<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:value-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;@ClassName&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
							<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
							<span style="color: #808080; font-style: italic;">&lt;!-- Copy the children (Columns etc) --&gt;</span>
							<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;xsl:copy-of</span> <span style="color: #000066;">select</span>=<span style="color: #ff0000;">&quot;$database/sql:Database/sql:Table[@Name=$sqlName]/sql:Type/*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
						<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:element<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:element<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:if<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:for-each<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:element<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/xsl:stylesheet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>
<strong>generate.bat</strong></p>
<p>This is my entire generate.bat file, you can glean the input arguments from the custom build target above.</p>

<div class="wp_codebox"><table><tr id="p79924"><td class="code" id="p799code24"><pre class="bat" style="font-family:monospace;">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Generate LINQ to SQL classes based on tables defined in an xml config
::
&nbsp;
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
&nbsp;
setlocal 
&nbsp;
set SQLMETAL=&lt;put your path here!&gt;\sdk\Win2008\Bin\sqlmetal.exe
set MSXSL=&lt;put your path here!&gt;\msxsl.exe
&nbsp;
set PRJDIR=%1%
set PREDIR=%PRJDIR%Prebuild\
&nbsp;
set NAMESPACE=%2
&nbsp;
set METALOUT=%PREDIR%%3
set METALIN=%PREDIR%%4
&nbsp;
set COMPILETESTCLASS=%PRJDIR%%5
set CONTEXTCLASS=%6
set CONTEXTCLASSFILE=%PRJDIR%%CONTEXTCLASS%.Generated.cs
&nbsp;
set CONFIGPATH=%PREDIR%%7
set DATABASE=%8
&nbsp;
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
&nbsp;
echo ================ Generation of LINQ to SQL classes started ================
echo Using %CONFIGPATH%
&nbsp;
echo 1. Building %METALOUT% for entire %DATABASE% database 
%SQLMETAL% /conn:&quot;server=localhost; database=%DATABASE%;Integrated Security=SSPI&quot; /dbml:%METALOUT%
if errorlevel 1 goto :Failed
&nbsp;
echo 2. Generating %COMPILETESTCLASS% to test linq to sql types were generated correctly at compile time
%MSXSL% %CONFIGPATH% %PREDIR%GenerateTestTypes.xslt -o %COMPILETESTCLASS%
if errorlevel 1 goto :Failed
&nbsp;
echo 3. Building %METALIN% from %CONFIGPATH%
%MSXSL% %CONFIGPATH% %PREDIR%DbmlPruner.xslt -o %METALIN%
if errorlevel 1 goto :Failed
&nbsp;
echo 4. Generating %CONTEXTCLASSFILE% using %METALIN%
%SQLMETAL% %METALIN% /code:%CONTEXTCLASSFILE% /language:csharp /context:%CONTEXTCLASS% /namespace:%NAMESPACE% /serialization:Unidirectional
if errorlevel 1 goto :Failed
&nbsp;
echo ======== Generation of LINQ to SQL classes completed successfully =========
endlocal
goto :EOF
&nbsp;
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:Failed
&nbsp;
echo Configuration %CONFIG% FAILED
endlocal
exit /B 1</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.hypercomplex.co.uk/index.php/2010/03/filtering-sqlmetal-output-using-xslt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

