<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Inane Ramblings of a .NET Developer</title>
    <link>http://www.inaneramblings.com/</link>
    <description />
    <language>en-us</language>
    <copyright>Stuart Wheelwright</copyright>
    <lastBuildDate>Thu, 20 Dec 2007 21:45:14 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>stuart.wheelwright@gmail.com</managingEditor>
    <webMaster>stuart.wheelwright@gmail.com</webMaster>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=41d0323b-954d-48cb-b1fb-78ebb3460f61</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,41d0323b-954d-48cb-b1fb-78ebb3460f61.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,41d0323b-954d-48cb-b1fb-78ebb3460f61.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=41d0323b-954d-48cb-b1fb-78ebb3460f61</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm re-writing a Windows Form application using WPF as a way to<br />
understand the basics. For a while I was banging my head against the<br />
wall trying to do something really simple.<br />
I was trying to launch another WPF window (form) as a modal dialiog<br />
using ShowDialog as I would have done in wwindows Forms. Every time I<br />
ran the application a large, blank white window appeared when the<br />
ShowDialog call was made. This confused me until I realised I had<br />
simply, accidentally deleted the designer-generated<br />
InitializeComponent(); call from the Window's constructor.
</p>
        <p>
These things always seem so obvious afterwards!
</p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=41d0323b-954d-48cb-b1fb-78ebb3460f61" />
      </body>
      <title>WPF - White Rectangle Instead of Window</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,41d0323b-954d-48cb-b1fb-78ebb3460f61.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,41d0323b-954d-48cb-b1fb-78ebb3460f61.aspx</link>
      <pubDate>Thu, 20 Dec 2007 21:45:14 GMT</pubDate>
      <description>&lt;p&gt;
I'm re-writing a Windows Form application using WPF as a way to&lt;br&gt;
understand the basics. For a while I was banging my head against the&lt;br&gt;
wall trying to do something really simple.&lt;br&gt;
I was trying to launch another WPF window (form) as a modal dialiog&lt;br&gt;
using ShowDialog as I would have done in wwindows Forms. Every time I&lt;br&gt;
ran the application a large, blank white window appeared when the&lt;br&gt;
ShowDialog call was made. This confused me until I realised I had&lt;br&gt;
simply, accidentally deleted the designer-generated&lt;br&gt;
InitializeComponent(); call from the Window's constructor.
&lt;/p&gt;
&lt;p&gt;
These things always seem so obvious afterwards!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=41d0323b-954d-48cb-b1fb-78ebb3460f61" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,41d0323b-954d-48cb-b1fb-78ebb3460f61.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=c2e60c18-5242-40cc-8db6-b21ac6644c1c</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,c2e60c18-5242-40cc-8db6-b21ac6644c1c.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,c2e60c18-5242-40cc-8db6-b21ac6644c1c.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c2e60c18-5242-40cc-8db6-b21ac6644c1c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="ExternalClass" id="MessageBodyText">
          <div>The simple way to average (or more accurately known as 'find the <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">arithmetic
mean</a> of') a list of numbers is to add them all up and divide by the number
of items.
</div>
          <div> 
</div>
          <div>E.g.
</div>
          <div>The average of: 6, 2, 4, 5, 6, 3, 2 is 4:
</div>
          <div>6+2+4+5+6+3+2 = 28
</div>
          <div>28/7=4
</div>
          <div> 
</div>
          <div>Yesterday, we had the need to keep recalculating the average on the fly
as more data is received so the user could be constantly informed of the current average.
Using the classic algorithm would result in a degradation of performance over time
so we chose an alternative.
</div>
          <div>The basic idea behind the continuous average is to keep track of the total number
of items and current average as you go. Then, when a new number comes along work
out how far above or below the current average it is and divide it by the number of
items so far. This results in an 'adjustment' value that is used to 'correct' the
current average to take account of the new value.
</div>
          <div> 
</div>
          <div>Here's a simple C# class that implements the algorithm<font size="1"></font></div>
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> ContinuousAverage 
<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> count <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0; <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span>?
currentAverage <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span> ; <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> Average <br />
   {<br />
      get <br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      if</span> (currentAverage
== <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>) <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         throw</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> InvalidOperationException
(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"No
numbers have been averaged"</span>); <br />
   <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      return</span> currentAverage.Value; <br />
      }<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Count <br />
   {<br />
      get { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> count;
} <br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Add(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> number) <br />
   {<br />
      count++;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      if</span> (currentAverage
== <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>) <br />
      {<br />
         currentAverage <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> number;<br />
      }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      else</span> <br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         decimal</span> differenceFromAverage <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> number <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> currentAverage.Value; <br />
         currentAverage += differenceFromAverage <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/</span> count;<br />
      }<br />
   }<br />
}<br /><br />
[TestFixture] 
<br /></span>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> ContinuousAverageTests<br />
{</span>
              <br />
   [Test] <br />
   [ExpectedException(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(InvalidOperationException
), <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"No
numbers have been averaged"</span>)] <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> TestAverageOfNoItemsThrowsException(
) <br />
   {<br />
      MovingAverage movingAverage <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MovingAverage
(); <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      decimal</span> value <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> movingAverage.Average; <br />
   }<br /><br />
   [Test] <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> TestAverageOfOneItemIsItemValue(
) <br />
   {<br />
      MovingAverage movingAverage <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MovingAverage
(); <br />
      movingAverage.Add( 1.234M );<br /><br />
      Assert.AreEqual( 1.234M, movingAverage.Average
); <br />
   }<br /><br />
   [Test] <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> TestAverageOfSeveralItemsIsStandardArithmeticMean() <br />
   {<br />
      MovingAverage movingAverage <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MovingAverage
(); <br /><br />
      movingAverage.Add(6);<br />
      movingAverage.Add(2);<br />
      movingAverage.Add(4);<br />
      movingAverage.Add(5);<br />
      movingAverage.Add(6);<br />
      movingAverage.Add(3);<br />
      movingAverage.Add(2);<br /><br />
      Assert.AreEqual(7, movingAverage.Count);<br />
      Assert.AreEqual(4, movingAverage.Average, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"(6+2+4+5+6+3+2)/7
= (28/7) = 4"</span>); <br />
   }<br /></span>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">}<br /></span>
          </p>
        </div>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=c2e60c18-5242-40cc-8db6-b21ac6644c1c" />
      </body>
      <title>Fast algorithm for continuous mean</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,c2e60c18-5242-40cc-8db6-b21ac6644c1c.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,c2e60c18-5242-40cc-8db6-b21ac6644c1c.aspx</link>
      <pubDate>Fri, 05 Oct 2007 07:06:23 GMT</pubDate>
      <description>&lt;div class=ExternalClass id=MessageBodyText&gt;
&lt;div&gt;The simple way to average (or more accurately known as 'find the &lt;a href="http://en.wikipedia.org/wiki/Arithmetic_mean"&gt;arithmetic
mean&lt;/a&gt;&amp;nbsp;of') a list of numbers is to add them all up and divide by the number
of items.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;E.g.
&lt;/div&gt;
&lt;div&gt;The average of: 6, 2, 4, 5, 6, 3, 2 is 4:
&lt;/div&gt;
&lt;div&gt;6+2+4+5+6+3+2 = 28
&lt;/div&gt;
&lt;div&gt;28/7=4
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;Yesterday, we had the need to keep recalculating&amp;nbsp;the average on the fly
as more data is received so the user could be constantly informed of the current average.
Using the classic algorithm would result in a degradation of performance over time
so we chose&amp;nbsp;an alternative.
&lt;/div&gt;
&lt;div&gt;The basic idea behind the continuous average is to keep track of the total number
of items and current average&amp;nbsp;as you go. Then, when a new number comes along work
out how far above or below the current average it is and divide it by the number of
items so far. This results in an 'adjustment' value that is used to 'correct' the
current average to take account of the new value.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;Here's a simple C# class that implements the algorithm&lt;font size=1&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; ContinuousAverage 
&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; count &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt;?
currentAverage &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt; ;&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; Average&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (currentAverage
== &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; InvalidOperationException
(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"No
numbers have been averaged"&lt;/span&gt;);&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; currentAverage.Value;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; Count&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get { &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; count;
}&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Add(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; number)&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count++;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (currentAverage
== &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentAverage &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; number;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;/span&gt;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;decimal&lt;/span&gt; differenceFromAverage &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; number &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; currentAverage.Value;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentAverage += differenceFromAverage &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&lt;/span&gt; count;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[TestFixture] 
&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; ContinuousAverageTests&lt;br&gt;
{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;[Test]&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;[ExpectedException(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(InvalidOperationException
), &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"No
numbers have been averaged"&lt;/span&gt;)]&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; TestAverageOfNoItemsThrowsException(
)&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MovingAverage movingAverage &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MovingAverage
();&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;decimal&lt;/span&gt; value &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; movingAverage.Average;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;[Test]&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; TestAverageOfOneItemIsItemValue(
)&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MovingAverage movingAverage &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MovingAverage
();&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add( 1.234M );&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreEqual( 1.234M, movingAverage.Average
);&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;[Test]&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; TestAverageOfSeveralItemsIsStandardArithmeticMean()&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MovingAverage movingAverage &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MovingAverage
();&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add(6);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add(2);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add(4);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add(5);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add(6);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add(3);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;movingAverage.Add(2);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreEqual(7, movingAverage.Count);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreEqual(4, movingAverage.Average, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"(6+2+4+5+6+3+2)/7
= (28/7) = 4"&lt;/span&gt;);&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;}&lt;br&gt;
&lt;/p&gt;
&gt;&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=c2e60c18-5242-40cc-8db6-b21ac6644c1c" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,c2e60c18-5242-40cc-8db6-b21ac6644c1c.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=91598ef3-41f1-47e6-a283-1e9d1279c96d</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,91598ef3-41f1-47e6-a283-1e9d1279c96d.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,91598ef3-41f1-47e6-a283-1e9d1279c96d.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=91598ef3-41f1-47e6-a283-1e9d1279c96d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p class="EC_MsoNormal">
The difficulty with testing XML is that there are several ways of writing the same
thing and each of them is valid.
</p>
        <p class="EC_MsoNormal">
For example, the two XML snippets below are equivalent:
</p>
        <p class="EC_MsoNormal">
Indented XML using an explicit end tag to close empty elements:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;Person&gt;<br />
  &lt;FirstName&gt;&lt;/FirstName&gt;<br />
  &lt;LastName&gt;Smith&lt;/LastName&gt;<br />
&lt;/Person&gt;<br /></span>
          </p>
        </blockquote>
        <p class="EC_MsoNormal">
Non-indented XML with no additional whitespace and abbreviated empty tag:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;Person&gt;&lt;FirstName/&gt;&lt;LastName&gt;Smith&lt;/LastName&gt;&lt;/Person&gt;</span>
          </p>
        </blockquote>
        <p class="EC_MsoNormal">
XML Unit (<a href="http://xmlunit.sourceforge.net/" target="_blank"><font color="#0068cf">http://xmlunit.sourceforge.net/</font></a>)
allows you to test if two pieces of XML are equivalent:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[Test]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> TestEquivalentXmlFragmentsAreEqual(
)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   string</span> actualXml <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"&lt;Person&gt;&lt;FirstName/&gt;&lt;LastName&gt;Smith&lt;/LastName&gt;&lt;/Person&gt;"</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   string</span> expectedXml <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"&lt;Person&gt;\r\n
&lt;FirstName&gt;&lt;/FirstName&gt;\r\n &lt;LastName&gt;Smith&lt;/LastName&gt;&lt;/Person&gt;"</span>;<br /><br />
   XmlDiff xmlDifference <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> XmlDiff(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> StringReader(actualXml), <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> StringReader(expectedXml));<br />
   DiffResult result <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> xmlDifference.Compare();<br /><br />
   Assert.IsTrue(result.Equal);<br />
}<br /><br /></span>
          </p>
        </blockquote>
        <p class="EC_MsoNormal">
The only negative thing to say about XmlUnit is the information it provides when the
XML is not equivalent doesn’t make it particular easy to understand why the two pieces
of XML differ.
</p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=91598ef3-41f1-47e6-a283-1e9d1279c96d" />
      </body>
      <title>Unit testing XML</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,91598ef3-41f1-47e6-a283-1e9d1279c96d.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,91598ef3-41f1-47e6-a283-1e9d1279c96d.aspx</link>
      <pubDate>Wed, 26 Sep 2007 07:23:09 GMT</pubDate>
      <description>&lt;p class=EC_MsoNormal&gt;
The difficulty with testing XML is that there are several ways of writing the same
thing and each of them is valid.
&lt;/p&gt;
&lt;p class=EC_MsoNormal&gt;
For example,&amp;nbsp;the two XML snippets below are equivalent:
&lt;/p&gt;
&lt;p class=EC_MsoNormal&gt;
Indented XML using an explicit end tag to close empty elements:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;Person&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;FirstName&amp;gt;&amp;lt;/FirstName&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;LastName&amp;gt;Smith&amp;lt;/LastName&amp;gt;&lt;br&gt;
&amp;lt;/Person&amp;gt;&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p class=EC_MsoNormal&gt;
Non-indented XML with no additional whitespace and abbreviated empty tag:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;Person&amp;gt;&amp;lt;FirstName/&amp;gt;&amp;lt;LastName&amp;gt;Smith&amp;lt;/LastName&amp;gt;&amp;lt;/Person&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p class=EC_MsoNormal&gt;
XML Unit (&lt;a href="http://xmlunit.sourceforge.net/" target=_blank&gt;&lt;font color=#0068cf&gt;http://xmlunit.sourceforge.net/&lt;/font&gt;&lt;/a&gt;)
allows you to test if two pieces of XML are equivalent:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[Test]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; TestEquivalentXmlFragmentsAreEqual(
)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;string&lt;/span&gt; actualXml &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"&amp;lt;Person&amp;gt;&amp;lt;FirstName/&amp;gt;&amp;lt;LastName&amp;gt;Smith&amp;lt;/LastName&amp;gt;&amp;lt;/Person&amp;gt;"&lt;/span&gt;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;string&lt;/span&gt; expectedXml &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"&amp;lt;Person&amp;gt;\r\n
&amp;lt;FirstName&amp;gt;&amp;lt;/FirstName&amp;gt;\r\n &amp;lt;LastName&amp;gt;Smith&amp;lt;/LastName&amp;gt;&amp;lt;/Person&amp;gt;"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;XmlDiff xmlDifference &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; XmlDiff(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; StringReader(actualXml), &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; StringReader(expectedXml));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;DiffResult result &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; xmlDifference.Compare();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.IsTrue(result.Equal);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p class=EC_MsoNormal&gt;
The only negative thing to say about XmlUnit is the information it provides when the
XML is not equivalent doesn’t make it particular easy to understand why the two pieces
of XML differ.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=91598ef3-41f1-47e6-a283-1e9d1279c96d" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,91598ef3-41f1-47e6-a283-1e9d1279c96d.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=c77b6a30-57a0-46ed-bd07-d51c8bbc85b4</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,c77b6a30-57a0-46ed-bd07-d51c8bbc85b4.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,c77b6a30-57a0-46ed-bd07-d51c8bbc85b4.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c77b6a30-57a0-46ed-bd07-d51c8bbc85b4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last Friday I had the most infuriating day attempting to track down a problem with
our project's continuous build machine. It was one of those erratic, inconsistent
errors that prove tricky to pin down and it was occuring during registration of a
DLL. The weird thing was <a href="http://www.inaneramblings.com/PermaLink,guid,fa3d833b-fa82-4e9e-96c3-2d474a9820b7.aspx">Reggie</a> and
Regsvr32 were both reporting successful registration but MSBuild was failing in TlbImp
when attempting to create the CLR callable interop wrapper from the DLL saying the
DLL wasn't registered.
</p>
        <p>
Anyway, I finally tracked down the problem on Monday morning when other weird things
started happening. It turns out the Windows 2000 Server had run out of allocated
registry space. (see <a href="http://www.google.co.uk/search?hl=en&amp;q=windows+2000+registry+size">http://www.google.co.uk/search?hl=en&amp;q=windows+2000+registry+size</a>)
</p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=c77b6a30-57a0-46ed-bd07-d51c8bbc85b4" />
      </body>
      <title>Windows 2000 Registry Size</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,c77b6a30-57a0-46ed-bd07-d51c8bbc85b4.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,c77b6a30-57a0-46ed-bd07-d51c8bbc85b4.aspx</link>
      <pubDate>Tue, 10 Jul 2007 18:25:11 GMT</pubDate>
      <description>&lt;p&gt;
Last Friday I had the most infuriating day attempting to track down a problem with
our project's continuous build machine. It was one of those erratic, inconsistent
errors that prove tricky to pin down and it was occuring during registration of a
DLL. The weird thing was &lt;a href="http://www.inaneramblings.com/PermaLink,guid,fa3d833b-fa82-4e9e-96c3-2d474a9820b7.aspx"&gt;Reggie&lt;/a&gt;&amp;nbsp;and
Regsvr32 were both reporting successful registration but MSBuild was failing in TlbImp
when attempting to create the CLR callable interop wrapper from the DLL saying the
DLL wasn't registered.
&lt;/p&gt;
&lt;p&gt;
Anyway, I finally tracked down the problem on Monday morning when other weird things
started happening. It turns out the Windows 2000 Server had run&amp;nbsp;out of allocated
registry space. (see &lt;a href="http://www.google.co.uk/search?hl=en&amp;amp;q=windows+2000+registry+size"&gt;http://www.google.co.uk/search?hl=en&amp;amp;q=windows+2000+registry+size&lt;/a&gt;)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=c77b6a30-57a0-46ed-bd07-d51c8bbc85b4" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,c77b6a30-57a0-46ed-bd07-d51c8bbc85b4.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=61fba1d6-a030-4840-a633-b78cca2a92e0</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,61fba1d6-a030-4840-a633-b78cca2a92e0.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,61fba1d6-a030-4840-a633-b78cca2a92e0.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=61fba1d6-a030-4840-a633-b78cca2a92e0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">Recently, I came across some C# code that
was passing a <a href="http://msdn2.microsoft.com/en-us/library/490f96s2(VS.71).aspx">reference
type</a> to a method using the 'ref' keyword. Since reference types are inherently
passed by reference I was curious what effect the 'ref' keyword would have. 
<p>
One of my colleagues speculated it would work like a double dereference in C++ and a
little experimentation proved him correct.
</p><p>
The 'ref' keyword can be used to pass the reference of the reference to the object
which allows the method to assign a different object to be returned via the parameter<br /></p><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[Test] 
<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> TestPassingClassBasedObjectsByRef(
) 
<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> str1 <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"initial
value"</span>;</span></p><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
    PassStringInNormalWay( str1 );<br />
    Assert.AreEqual(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"initial
value"</span>, str1, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"str1
object is not altered"</span> ); 
<br /><br />
    PassStringByReference( <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ref</span> str1); <br />
    Assert.AreEqual(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"a"</span>,
str1, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"str1
is now a different object"</span>); 
<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> PassStringInNormalWay( <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> str
) 
<br />
{<br />
    str <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>(
'<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> value',
1 ); 
<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> PassStringByReference( <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ref</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> str) 
<br />
{<br />
    str <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>('<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> value',
1); 
<br />
}</span></p><img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=61fba1d6-a030-4840-a633-b78cca2a92e0" /></body>
      <title>Passing reference types by ref in C#</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,61fba1d6-a030-4840-a633-b78cca2a92e0.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,61fba1d6-a030-4840-a633-b78cca2a92e0.aspx</link>
      <pubDate>Sun, 27 May 2007 22:42:24 GMT</pubDate>
      <description>Recently, I came across some C# code that was passing a &lt;a href="http://msdn2.microsoft.com/en-us/library/490f96s2(VS.71).aspx"&gt;reference
type&lt;/a&gt; to a method using the 'ref' keyword. Since reference types are inherently
passed by reference I was curious what effect the 'ref' keyword would have. 
&lt;p&gt;
One of my colleagues speculated it would work like a double dereference in C++ and&amp;nbsp;a
little experimentation proved him correct.
&lt;/p&gt;
&lt;p&gt;
The 'ref' keyword can be used to pass the reference of the reference to the object
which allows the method to assign a different object to be returned via the parameter&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[Test] 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; TestPassingClassBasedObjectsByRef(
) 
&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; str1 &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"initial
value"&lt;/span&gt;;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PassStringInNormalWay( str1 );&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreEqual(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"initial
value"&lt;/span&gt;, str1, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"str1
object is not altered"&lt;/span&gt; ); 
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PassStringByReference( &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ref&lt;/span&gt; str1);&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreEqual(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"a"&lt;/span&gt;,
str1, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"str1
is now a different object"&lt;/span&gt;); 
&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; PassStringInNormalWay( &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; str
) 
&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;(
'&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; value',
1 ); 
&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; PassStringByReference( &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ref&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; str) 
&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;('&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; value',
1); 
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=61fba1d6-a030-4840-a633-b78cca2a92e0" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,61fba1d6-a030-4840-a633-b78cca2a92e0.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=11a79178-6fb1-4391-8ed8-eea338f99168</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,11a79178-6fb1-4391-8ed8-eea338f99168.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,11a79178-6fb1-4391-8ed8-eea338f99168.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=11a79178-6fb1-4391-8ed8-eea338f99168</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
A few weeks ago I developed a website for my sister to help promote her <a href="http://www.auroramobilebeauty.co.uk/">mobile
beauty therapist</a> business.
</p>
        <p>
Originally, I designed the website as a series of static html pages so we had the
greatest amount of freedom in choosing a web host which helps keep her hosting costs
down (There are loads of webhosts that will host basic websites for free with
the hope that once you're with them you'll purchase extra features. In the end we
settled for <a href="http://www.easyinternetsolutions.co.uk">http://www.easyinternetsolutions.co.uk</a> and
so far we've had no problems) 
</p>
        <p>
          <a href="http://www.auroramobilebeauty.co.uk/">
            <img height="323" src="http://www.inaneramblings.com/content/binary/aurora1.jpg" width="296" border="0" />
          </a>
        </p>
        <p>
Yesterday, I needed to make a small change to the website that would affect all five
pages and because I had manually created each of the pages it would be tedious to
make the change on each page. Also, in the back of my mind I knew the price list would
need updating on a regular basis to adjust the prices and to allow new treatments
to be added. These requirements led me to revisit the way I produce the static HTML.
</p>
        <p>
My idea was to extract all the dynamic portions of the website into an XML file then
apply an XSLT transformation to produce the static HTML pages.<br />
The XML contains:
</p>
        <ul>
          <li>
The intra-site navigation</li>
          <li>
Full price list</li>
          <li>
Links to other websites</li>
        </ul>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;links&gt;<br />
  &lt;link&gt;<br />
    &lt;text&gt;Guild of Professional Beauty Therapists&lt;/text&gt;<br />
    &lt;description&gt;The UKs biggest professional beauty trade body.
The Guild has over 5,000 members who are all fully qualified beauty and holistic therapists&lt;/description&gt;<br />
    &lt;url&gt;http:<span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//www.beautyguild.com/&lt;/url&gt;</span><br />
  &lt;/link&gt;<br />
&lt;/links&gt;<br />
&lt;priceList&gt; 
<br />
  &lt;section name=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Waxing"</span>&gt;<br />
    &lt;item text=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Lip"</span> duration=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"10
mins"</span> price=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"£4.50"</span>/&gt;<br />
    &lt;item text=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Chin"</span> duration=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"10
mins"</span> price=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"£4.50"</span>/&gt;<br /></span>
          </p>
        </blockquote>
        <p>
I created one XSLT document per output page and use <a href="http://nant.sourceforge.net/release/latest/help/tasks/style.html">nant's
style task</a> to apply the XSLT to the XML producing the HTML 
</p>
        <p>
e.g.
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;?xml
version=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"1.0"</span>?&gt;<br />
&lt;project <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">default</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"BuildWebSite"</span> basedir=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"."</span>&gt;<br />
    <br />
    &lt;target name=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"BuildWebSite"</span>&gt;<br /><br />
        &lt;style style=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"index.xslt"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"website.xml"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">out</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"..\WebSite\index.htm"</span> /&gt;<br />
        &lt;style style=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"treatments.xslt"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"website.xml"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">out</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"..\WebSite\treatments.htm"</span> /&gt;<br />
        &lt;style style=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"prices.xslt"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"website.xml"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">out</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"..\WebSite\prices.htm"</span> /&gt;<br />
        &lt;style style=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"contact.xslt"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"website.xml"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">out</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"..\WebSite\contact.htm"</span> /&gt;<br />
        &lt;style style=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"links.xslt"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"website.xml"</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">out</span>=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"..\WebSite\links.htm"</span> /&gt;<br />
        <br />
    &lt;/target&gt;<br />
            <br />
&lt;/project&gt;</span>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <br />
            </span>
          </p>
        </blockquote>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
 
</p>
        <p>
Now, changes can be made to the XML data and the whole site rebuilt with the click
of a button
</p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=11a79178-6fb1-4391-8ed8-eea338f99168" />
      </body>
      <title>Generating static websites from XML using XSLT</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,11a79178-6fb1-4391-8ed8-eea338f99168.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,11a79178-6fb1-4391-8ed8-eea338f99168.aspx</link>
      <pubDate>Tue, 22 May 2007 19:33:17 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
A few weeks ago I developed a website for my sister to help promote her &lt;a href="http://www.auroramobilebeauty.co.uk/"&gt;mobile
beauty therapist&lt;/a&gt; business.
&lt;/p&gt;
&lt;p&gt;
Originally, I designed the website as a series of static html pages so we had the
greatest amount of freedom in choosing a web host which helps keep her hosting costs
down (There are loads of webhosts that will host basic websites for free&amp;nbsp;with
the hope that once you're with them you'll purchase extra features. In the end we
settled for &lt;a href="http://www.easyinternetsolutions.co.uk"&gt;http://www.easyinternetsolutions.co.uk&lt;/a&gt;&amp;nbsp;and
so far we've had no problems)&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.auroramobilebeauty.co.uk/"&gt;&lt;img height=323 src="http://www.inaneramblings.com/content/binary/aurora1.jpg" width=296 border=0&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Yesterday, I needed to make a small change to the website that would affect all five
pages and because I had manually created each of the pages it would be tedious to
make the change on each page. Also, in the back of my mind I knew the price list would
need updating on a regular basis to adjust the prices and to allow new treatments
to be added. These requirements led me to revisit the way I produce the static HTML.
&lt;/p&gt;
&lt;p&gt;
My idea was to extract all the dynamic portions of the website into an XML file then
apply an XSLT transformation to produce the static HTML pages.&lt;br&gt;
The XML contains:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The intra-site navigation&lt;/li&gt;
&lt;li&gt;
Full price list&lt;/li&gt;
&lt;li&gt;
Links to other websites&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;links&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;link&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;text&amp;gt;Guild of Professional Beauty Therapists&amp;lt;/text&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;description&amp;gt;The UKs biggest professional beauty trade body.
The Guild has over 5,000 members who are all fully qualified beauty and holistic therapists&amp;lt;/description&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;url&amp;gt;http:&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//www.beautyguild.com/&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;/link&amp;gt;&lt;br&gt;
&amp;lt;/links&amp;gt;&lt;br&gt;
&amp;lt;priceList&amp;gt; 
&lt;br&gt;
&amp;nbsp; &amp;lt;section name=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Waxing"&lt;/span&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;item text=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Lip"&lt;/span&gt; duration=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"10
mins"&lt;/span&gt; price=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"£4.50"&lt;/span&gt;/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;item text=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Chin"&lt;/span&gt; duration=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"10
mins"&lt;/span&gt; price=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"£4.50"&lt;/span&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I created one XSLT document per output page and use &lt;a href="http://nant.sourceforge.net/release/latest/help/tasks/style.html"&gt;nant's
style task&lt;/a&gt; to apply the XSLT to the XML producing the HTML 
&lt;/p&gt;
&lt;p&gt;
e.g.
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;?xml
version=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"1.0"&lt;/span&gt;?&amp;gt;&lt;br&gt;
&amp;lt;project &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;default&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"BuildWebSite"&lt;/span&gt; basedir=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"."&lt;/span&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;target name=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"BuildWebSite"&lt;/span&gt;&amp;gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;style style=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"index.xslt"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"website.xml"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;out&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"..\WebSite\index.htm"&lt;/span&gt; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;style style=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"treatments.xslt"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"website.xml"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;out&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"..\WebSite\treatments.htm"&lt;/span&gt; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;style style=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"prices.xslt"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"website.xml"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;out&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"..\WebSite\prices.htm"&lt;/span&gt; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;style style=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"contact.xslt"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"website.xml"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;out&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"..\WebSite\contact.htm"&lt;/span&gt; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;style style=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"links.xslt"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"website.xml"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;out&lt;/span&gt;=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"..\WebSite\links.htm"&lt;/span&gt; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;lt;/project&amp;gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Now, changes can be made to the XML data and the whole site rebuilt with the click
of a button
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=11a79178-6fb1-4391-8ed8-eea338f99168" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,11a79178-6fb1-4391-8ed8-eea338f99168.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=78e8e380-6740-4282-998a-245dfb996ff9</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,78e8e380-6740-4282-998a-245dfb996ff9.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,78e8e380-6740-4282-998a-245dfb996ff9.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=78e8e380-6740-4282-998a-245dfb996ff9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently, I was modifying an XSLT template for generating code and I needed to convert
a Property name into camelCase (e.g. FirstName becomes firstName). I initially tried
calling an XSLT template but soon reached the limits of what can be achieved in XSLT
(or at least the limit of my knowledge!) without resorting to complex, unmanageable
code.
</p>
        <p>
Luckily, I stumbled across this <a href="http://msdn.microsoft.com/msdnmag/issues/02/03/xml/">article</a> on
MSDN describing how C# can be embedded in an XSLT document as a CDATA block and called
in the same way as built in functions. Note: As far as I know, this only works if
you are using the Microsoft MSXML 4.0 or .NET to perform the transformation.
</p>
        <p>
The C# code must be enclosed in a ms:script element and, for readability, should be
inside a CDATA block.
</p>
        <p>
E.g.
</p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;ms:script
language=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"C#"</span> implements-prefix=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"usr"</span>&gt;<br />
  &lt;![CDATA[<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> ToCamelCase( <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> str
)<br />
    {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">     
if</span> (String.IsNullOrEmpty(str))<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">       
return</span> str;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">     
else</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">       
return</span> str.Substring(0, 1).ToLower() <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> str.Substring(1);<br />
    }<br />
  ]]&gt;<br />
&lt;/ms:script&gt;</span>
          </p>
        </span>
        <p>
All namespaces must be declared in the stylesheet header:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;xsl:stylesheet
version=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"1.0"</span><br />
xmlns:xsl=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"http://www.w3.org/1999/XSL/Transform"</span><br />
xmlns:<strong>ms=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"urn:schemas-microsoft-com:xslt"</span></strong><br />
xmlns:<strong>usr=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"urn:my-namespace"</span></strong>&gt;</span>
        </p>
        <p>
Now the new C# method can be called from within the stylesheet like this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;xsl:value-of
select=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"usr:ToCamelCase(title)"</span>/&gt;</span>
        </p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=78e8e380-6740-4282-998a-245dfb996ff9" />
      </body>
      <title>Using C# in XSLT</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,78e8e380-6740-4282-998a-245dfb996ff9.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,78e8e380-6740-4282-998a-245dfb996ff9.aspx</link>
      <pubDate>Fri, 18 May 2007 08:24:27 GMT</pubDate>
      <description>&lt;p&gt;
Recently, I was modifying an XSLT template for generating code and I needed to convert
a Property name into camelCase (e.g. FirstName becomes firstName). I initially tried
calling an XSLT template but soon reached the limits of what can be achieved in XSLT
(or at least the limit of my knowledge!) without resorting to complex, unmanageable
code.
&lt;/p&gt;
&lt;p&gt;
Luckily, I stumbled across this &lt;a href="http://msdn.microsoft.com/msdnmag/issues/02/03/xml/"&gt;article&lt;/a&gt;&amp;nbsp;on
MSDN describing how C# can be embedded in an XSLT document as a CDATA block and called
in the same way as built in functions. Note: As far as I know, this only works if
you are using the&amp;nbsp;Microsoft MSXML 4.0 or .NET to perform the transformation.
&lt;/p&gt;
&lt;p&gt;
The C# code must be enclosed in a ms:script element and, for readability, should be
inside a CDATA block.
&lt;/p&gt;
&lt;p&gt;
E.g.
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;ms:script
language=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"C#"&lt;/span&gt; implements-prefix=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"usr"&lt;/span&gt;&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;![CDATA[&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; ToCamelCase( &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; str
)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (String.IsNullOrEmpty(str))&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return&lt;/span&gt; str;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
else&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return&lt;/span&gt; str.Substring(0, 1).ToLower() &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; str.Substring(1);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp; ]]&amp;gt;&lt;br&gt;
&amp;lt;/ms:script&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/span&gt; 
&lt;p&gt;
All namespaces must be declared in the stylesheet header:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;xsl:stylesheet
version=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"1.0"&lt;/span&gt;
&lt;br&gt;
xmlns:xsl=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"http://www.w3.org/1999/XSL/Transform"&lt;/span&gt;
&lt;br&gt;
xmlns:&lt;strong&gt;ms=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"urn:schemas-microsoft-com:xslt"&lt;/span&gt;&lt;/strong&gt;
&lt;br&gt;
xmlns:&lt;strong&gt;usr=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"urn:my-namespace"&lt;/span&gt;&lt;/strong&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Now the new C# method can be called from within the stylesheet like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;xsl:value-of
select=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"usr:ToCamelCase(title)"&lt;/span&gt;/&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=78e8e380-6740-4282-998a-245dfb996ff9" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,78e8e380-6740-4282-998a-245dfb996ff9.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=3207c3d8-84a0-41fb-9413-4aeb34285f2c</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,3207c3d8-84a0-41fb-9413-4aeb34285f2c.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,3207c3d8-84a0-41fb-9413-4aeb34285f2c.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3207c3d8-84a0-41fb-9413-4aeb34285f2c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p class="MsoNormal">
In my current project we’re migrating a solution from Visual FoxPro to .NET and SQL
Server in a two-stage process. First the business logic will be re-written in C#,
and finally the database layer will be switched to SQL Server.
</p>
        <p class="MsoNormal">
To complicate things there are several tables in the database that contain sensitive
data and so they are encrypted with a 3rd party utility which makes using ODBC data
access impossible. Instead, all data access is done through a DLL written in FoxPro
that is auto-generated from the domain model’s metadata. This DLL must be rebuilt
every time the metadata changes and this currently has to be done by hand by the developer
on their own machine. This is currently the manual only step in our automated build
process and I’ve been looking for a way to automate it.
</p>
        <p class="MsoNormal">
I’ve finally had the chance to sit down and investigate this and it turns out I can
use the Foxpro COM DLL Vfp6t.dll:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> vfpProjectPath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Path.Combine(
Environment.CurrentDirectory, args[0] );<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> outputDll <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Path.Combine(
Environment.CurrentDirectory, args[1] );<br /><br />
Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Building
'{0}' from FoxPro project '{1}'"</span>, outputDll, vfpProjectPath );<br /><br />
FoxApplicationClass vfp <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> FoxApplicationClass(
);<br />
vfp.DoCmd( String.Format( <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"BUILD
DLL {0} FROM {1} RECOMPILE"</span>, outputDll, vfpProjectPath ) );<br />
vfp.Quit( );<br /></span>
          </p>
        </blockquote>
        <p class="MsoNormal">
The only drawback is if an error occurs during the build a nasty message box pops
up which is not so great when it occurs on the automated build machine
</p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=3207c3d8-84a0-41fb-9413-4aeb34285f2c" />
      </body>
      <title>Automating Visual FoxPro DLL Build Process</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,3207c3d8-84a0-41fb-9413-4aeb34285f2c.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,3207c3d8-84a0-41fb-9413-4aeb34285f2c.aspx</link>
      <pubDate>Mon, 14 May 2007 20:42:45 GMT</pubDate>
      <description>&lt;p class=MsoNormal&gt;
In my current project we’re migrating a solution from Visual FoxPro to .NET and SQL
Server in a two-stage process. First the business logic will be re-written in C#,
and finally the database layer will be switched to SQL Server.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
To complicate things there are several tables in the database that contain sensitive
data and so they are encrypted with a 3rd party utility which makes using ODBC data
access impossible. Instead, all data access is done through a DLL written in FoxPro
that is auto-generated from the domain model’s metadata. This DLL must be rebuilt
every time the metadata changes and this currently has to be done by hand by the developer
on their own machine. This is currently the manual only step in our automated build
process and I’ve been looking for a way to automate it.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
I’ve finally had the chance to sit down and investigate this and it turns out I can
use the Foxpro COM DLL Vfp6t.dll:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; vfpProjectPath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Path.Combine(
Environment.CurrentDirectory, args[0] );&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; outputDll &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Path.Combine(
Environment.CurrentDirectory, args[1] );&lt;br&gt;
&lt;br&gt;
Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Building
'{0}' from FoxPro project '{1}'"&lt;/span&gt;, outputDll, vfpProjectPath );&lt;br&gt;
&lt;br&gt;
FoxApplicationClass vfp &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; FoxApplicationClass(
);&lt;br&gt;
vfp.DoCmd( String.Format( &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"BUILD
DLL {0} FROM {1} RECOMPILE"&lt;/span&gt;, outputDll, vfpProjectPath ) );&lt;br&gt;
vfp.Quit( );&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p class=MsoNormal&gt;
The only drawback is if an error occurs during the build a nasty message box pops
up which is not so great when it occurs on the automated build machine
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=3207c3d8-84a0-41fb-9413-4aeb34285f2c" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,3207c3d8-84a0-41fb-9413-4aeb34285f2c.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=fa3d833b-fa82-4e9e-96c3-2d474a9820b7</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,fa3d833b-fa82-4e9e-96c3-2d474a9820b7.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,fa3d833b-fa82-4e9e-96c3-2d474a9820b7.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=fa3d833b-fa82-4e9e-96c3-2d474a9820b7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today I came across a problem with an installation script for a deployment package
I’m putting together. Basically, I had a batch file that called regsvr32 with the
/s switch (silent option so message boxes don't pop up) to register some DLLs and
the registration was failing (due to FoxPro runtime files not being installed) but
regsvr32 didn’t report any errors! I have since switched to using <a href="http://www.windojitsu.com/tech/reggie.html">reggie.exe</a> a
regsvr32 replacement that thoughtfully provides nice error messages.
</p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=fa3d833b-fa82-4e9e-96c3-2d474a9820b7" />
      </body>
      <title>The Silent Failings of Regsvr32 </title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,fa3d833b-fa82-4e9e-96c3-2d474a9820b7.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,fa3d833b-fa82-4e9e-96c3-2d474a9820b7.aspx</link>
      <pubDate>Fri, 11 May 2007 00:20:11 GMT</pubDate>
      <description>&lt;p&gt;
Today I came across a problem with an installation script for a deployment package
I’m putting together. Basically, I had a batch file that called regsvr32 with the
/s switch (silent option so message boxes don't pop up) to register some DLLs and
the registration was failing (due to FoxPro runtime files not being installed) but
regsvr32 didn’t report any errors! I have since switched to using &lt;a href="http://www.windojitsu.com/tech/reggie.html"&gt;reggie.exe&lt;/a&gt; a
regsvr32 replacement that thoughtfully provides nice error messages.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=fa3d833b-fa82-4e9e-96c3-2d474a9820b7" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,fa3d833b-fa82-4e9e-96c3-2d474a9820b7.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=9dba4521-29f4-404a-938f-404a93c78c5c</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,9dba4521-29f4-404a-938f-404a93c78c5c.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,9dba4521-29f4-404a-938f-404a93c78c5c.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=9dba4521-29f4-404a-938f-404a93c78c5c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've <a href="http://www.inaneramblings.com/PermaLink,guid,3cb60877-5d0c-4f3e-82a2-60f580025f8f.aspx">written
previously</a> about using log4net to log system events for diagnostic purposes in
development and live environments and how its configuration is so flexible the output
can be sent anywhere. Well, recently, I've been developing a client-server application
that uses WSE 3.0 to communicate using web messages and to make the initial
development simpler we opted to host the server component in a Windows Form so
it can be easily started and stopped. I figured that since we had already littered
the server with appropriate logging that we might as well show this in the server's
GUI and watch the live diagnostic information as messages are received and processed.
</p>
        <p>
          <img height="205" alt="ServerLogViewerDemo.gif" src="http://www.inaneramblings.com/content/binary/ServerLogViewerDemo.gif" width="685" border="0" />
        </p>
        <p>
Due to log4net's clean, modular design it is quite simple to achieve what I need.
</p>
        <p>
First, we need to configure the app.config to send log entries to a MemoryAppender
by adding a new appender to the log4net section
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New" size="1">&lt;appender name="LogViewerDemo" type="log4net.Appender.MemoryAppender"&gt;<br /></font>
            <font face="Courier New" size="1">  &lt;layout type="log4net.Layout.PatternLayout"&gt;<br /></font>
            <font face="Courier New" size="1">    &lt;conversionPattern
value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /&gt;<br /></font>
            <font face="Courier New" size="1">  &lt;/layout&gt;<br /></font>
            <font face="Courier New" size="1">&lt;/appender&gt;</font>
          </p>
        </blockquote>
        <p>
and specifying the appender name in the root section:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New" size="1">&lt;appender-ref ref="LogViewerDemo" /&gt;</font>
          </p>
        </blockquote>
        <p>
Next we write a UserControl containing a RichTextBox and a Timer. Every second, the
timer will ask log4net for the MemoryAppender with the name 'LogViewerDemo' and output
any new events received since the last timer tick to the RichTextBox.
</p>
        <p>
Obtaining the MemoryAppender:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Hierarchy
loggerHierarchy <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> LogManager.GetRepository() <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">as</span> Hierarchy;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (loggerHierarchy
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
{<br />
   logMemoryAppender <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> loggerHierarchy.Root.GetAppender(appenderName) <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">as</span> MemoryAppender;<br />
}</span>
          </p>
        </blockquote>
        <p dir="ltr">
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" color="#003300" size="2">Fetching
the log events:</font>
          </span>
        </p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <font face="Verdana" color="#003300" size="2">
            <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
              <p>
                <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">LoggingEvent[]
events <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> logMemoryAppender.GetEvents();<br />
logMemoryAppender.Clear();<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span> (LoggingEvent
logEvent <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> events)<br />
{<br />
   WriteLogEventToLogTextBox(logEvent);<br />
}</span>
              </p>
            </blockquote>
          </font>
        </span>
        <p dir="ltr">
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" color="#003300" size="2">Finally,
all that is left is to append the event details to the end of the RichTextBox having
first coloured the text red, orange or black to indicate the logging levels of 'Error',
'Warning' and 'anything else' respectively.</font>
          </span>
        </p>
        <p dir="ltr">
          <a href="http://www.inaneramblings.com/content/binary/Log4NetViewerDemo.zip">Log4NetViewerDemo.zip
(13.91 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=9dba4521-29f4-404a-938f-404a93c78c5c" />
      </body>
      <title>log4net Viewer Control</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,9dba4521-29f4-404a-938f-404a93c78c5c.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,9dba4521-29f4-404a-938f-404a93c78c5c.aspx</link>
      <pubDate>Thu, 10 May 2007 22:09:07 GMT</pubDate>
      <description>&lt;p&gt;
I've &lt;a href="http://www.inaneramblings.com/PermaLink,guid,3cb60877-5d0c-4f3e-82a2-60f580025f8f.aspx"&gt;written
previously&lt;/a&gt; about using log4net to log system events for diagnostic purposes in
development and live environments and how its configuration is so flexible the output
can be sent anywhere. Well, recently, I've been developing a client-server application
that uses WSE 3.0 to communicate using web messages&amp;nbsp;and&amp;nbsp;to make the initial
development simpler we opted to host the server component in&amp;nbsp;a Windows Form so
it can be easily started and stopped. I figured that since we had already littered
the server with appropriate logging that we might as well show this in the server's
GUI and watch the live diagnostic information as messages are received and processed.
&lt;/p&gt;
&lt;p&gt;
&lt;img height=205 alt=ServerLogViewerDemo.gif src="http://www.inaneramblings.com/content/binary/ServerLogViewerDemo.gif" width=685 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Due to log4net's clean, modular design it is quite simple to achieve what I need.
&lt;/p&gt;
&lt;p&gt;
First, we need to configure the app.config to send log entries to a MemoryAppender
by adding a new appender to the log4net section
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;font face="Courier New" size=1&gt;&amp;lt;appender name="LogViewerDemo" type="log4net.Appender.MemoryAppender"&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=1&gt;&amp;nbsp; &amp;lt;layout type="log4net.Layout.PatternLayout"&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;conversionPattern value="%date
[%thread] %-5level %logger [%property{NDC}] - %message%newline" /&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=1&gt;&amp;nbsp; &amp;lt;/layout&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=1&gt;&amp;lt;/appender&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
and specifying the appender name in the root section:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;font face="Courier New" size=1&gt;&amp;lt;appender-ref ref="LogViewerDemo" /&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Next we write a UserControl containing a RichTextBox and a Timer. Every second, the
timer will ask log4net for the MemoryAppender with the name 'LogViewerDemo' and output
any new events received since the last timer tick to the RichTextBox.
&lt;/p&gt;
&lt;p&gt;
Obtaining the MemoryAppender:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Hierarchy
loggerHierarchy &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; LogManager.GetRepository() &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;as&lt;/span&gt; Hierarchy;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (loggerHierarchy
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;logMemoryAppender &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; loggerHierarchy.Root.GetAppender(appenderName) &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;as&lt;/span&gt; MemoryAppender;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt;Fetching
the log events:&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt; &lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;LoggingEvent[]
events &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; logMemoryAppender.GetEvents();&lt;br&gt;
logMemoryAppender.Clear();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;foreach&lt;/span&gt; (LoggingEvent
logEvent &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; events)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteLogEventToLogTextBox(logEvent);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;/font&gt;&lt;/span&gt; 
&lt;p dir=ltr&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt;Finally,
all that is left is to append the event details to the end of the RichTextBox having
first coloured the text red, orange or black to indicate the logging levels of 'Error',
'Warning' and 'anything else' respectively.&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;a href="http://www.inaneramblings.com/content/binary/Log4NetViewerDemo.zip"&gt;Log4NetViewerDemo.zip
(13.91 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=9dba4521-29f4-404a-938f-404a93c78c5c" /&gt;</description>
      <comments>http://www.inaneramblings.com/CommentView,guid,9dba4521-29f4-404a-938f-404a93c78c5c.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.inaneramblings.com/Trackback.aspx?guid=3cb60877-5d0c-4f3e-82a2-60f580025f8f</trackback:ping>
      <pingback:server>http://www.inaneramblings.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.inaneramblings.com/PermaLink,guid,3cb60877-5d0c-4f3e-82a2-60f580025f8f.aspx</pingback:target>
      <dc:creator>Stu</dc:creator>
      <wfw:comment>http://www.inaneramblings.com/CommentView,guid,3cb60877-5d0c-4f3e-82a2-60f580025f8f.aspx</wfw:comment>
      <wfw:commentRss>http://www.inaneramblings.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3cb60877-5d0c-4f3e-82a2-60f580025f8f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In any non-trivial project, especially when the application is split across several
tiers, I find adding a few logging statements has a real benefit. I have used <a href="http://logging.apache.org/log4net/">log4net</a> in
the last four enterprise-level projects I've worked on and it is a marked improvement
on the standard System.Diagnostics.Trace and Debug classes.
</p>
        <p class="MsoNormal">
          <span lang="EN-GB">log4Net is an open source logging tool that allows all aspects
of logging to be modified by changing the config file, which can be done after
the code has been built and is in production. This config file controls which messages
are logged, the format of messages and where log messages are sent. </span>
          <span lang="EN-GB" style="COLOR: windowtext">
          </span>
        </p>
        <p class="MsoNormal">
          <span lang="EN-GB">For example, once the application is in production you may decide
to have certain messages, for example errors and warnings, emailed to the developer
and system admin whilst all other informational messages are logged to a text file.
(This is the approach I used for <a href="http://www.partyhandbook.co.uk/">PartyHandbook</a> so
I get immediate notification when an exception is thrown or a warning generated).
Setting this up is just a matter of adding a few lines to the config file and can
be configured such that the application doesn't even need a restart. See <a href="javascript:ol('http://logging.apache.org/log4net/release/config-examples.html%23smtpappender');">http://logging.apache.org/log4net/release/config-examples.html#smtpappender</a> for
details of the email appender. </span>
        </p>
        <p class="MsoNormal">
          <span lang="EN-GB">The logging facilities are also useful in tracking down specific
bugs in the live system. Imagine </span>you have a system performing complicated
calculat<span lang="EN-GB">ions and you've received a report that the resulting value is
not as you'd expect. Assuming sufficient logging has been placed in the application,
this would be as simple as turning on 'Debug' level log messages for the <font face="Courier New">MyProduct.ServerServices.ComplicatedCalculationModule</font> and
we would see the calculation steps for the live system without having to recreate
the data and start the debugger up.</span></p>
        <p class="MsoNormal">
          <span lang="EN-GB">It does take a bit of practice to get into the habit of adding
log statements in the right places and in sufficient quantity to provide the required
level of verbosity but they can prove very useful in diagnosing problems and also
providing another level of documentation to the code. </span>
        </p>
        <p class="MsoNormal">
          <span lang="EN-GB">The areas I tend to add logging statements are:</span>
        </p>
        <ul>
          <li class="Bulleted">
            <span lang="EN-GB">In top-level exception handlers. E.g. in Global.asax Page_Error
method or in a try catch block wrapped around the Application.Run statement in the
static Main method of a windows application or service.</span>
          </li>
          <li class="Bulleted">
            <span lang="EN-GB">
            </span>
            <span lang="EN-GB">In security authentication code to log
failed login attempts</span>
          </li>
          <li>
            <div class="Bulleted">
              <span lang="EN-GB">In session handling code to determine when
web sessions or nhibernate sessions are started and stopped</span>
            </div>
          </li>
          <li>
            <div class="Bulleted">
              <span lang="EN-GB">To record configuration settings read in
from the config file (e.g. the database connection string used)</span>
            </div>
          </li>
          <li>
            <div class="Bulleted">
              <span lang="EN-GB">To record things that happen across process
boundaries. E.g. web service messages that are sent and received</span>
            </div>
          </li>
          <li>
            <div class="Bulleted">
              <span lang="EN-GB">User actions. E.g. when user runs a system
command by selecting a menu option or clicking a toolbar button.</span>
            </div>
          </li>
        </ul>
        <p class="MsoNormal">
          <span lang="EN-GB">Several other open source tools such as nHibernate also uses log4net
to record a whole host of useful information regarding database persistence (E.g.
the SQL statements are being sent to the database) so they can be configured in a
similar manner.</span>
        </p>
        <h1 style="TEXT-INDENT: 0cm">
          <a name="_Toc166039471">
            <span lang="EN-GB">Getting Started</span>
          </a>
        </h1>
        <p class="MsoNormal">
          <span lang="EN-GB">This is a 30 second guide to using log4net in a project.</span>
          <span lang="EN-GB">
          </span>
        </p>
        <ul>
          <li>
            <div class="MsoNormal">
              <span lang="EN-GB">Get hold of log4net.dll. This can be downloaded
from </span>
              <span lang="EN-GB">
                <a href="javascript:ol('http://logging.apache.org/log4net/downloads.html');">http://logging.apache.org/log4net/downloads.html</a>
              </span>
              <span lang="EN-GB">
              </span>
            </div>
          </li>
          <li>
            <div class="MsoNormal">
              <span lang="EN-GB">Add a reference to the DLL from your project</span>
            </div>
          </li>
          <li>
            <div class="MsoNormal">
              <span lang="EN-GB">Add the following line as the first line
in your application (in the Main( ) method for windows applications or in your global.asax
file): </span>
            </div>
          </li>
        </ul>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">XmlConfigurator.Configure();</span>
          </p>
        </blockquote>
        <ul>
          <li>
            <div class="MsoNormal">
              <span lang="EN-GB">Add the following line to the top of the
class you'd like to log:</span>
            </div>
          </li>
        </ul>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <font size="2">
            <font color="#20879c">
              <font face="Courier New">
                <span lang="EN-GB">
                  <p>
                    <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                      <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
                      <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
                      <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">readonly</span> ILog
m_Log <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> LogManager.GetLogger( <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(MyClass)
); </span>
                  </p>
                </span>
              </font>
            </font>
          </font>
        </blockquote>
        <ul>
          <li>
            <div class="MsoNormal">
              <span lang="EN-GB">Add logging statements to your code:</span>
            </div>
            <font size="2">
              <font color="#20879c">
                <font face="Courier New">
                  <span lang="EN-GB">
                  </span>
                </font>
              </font>
            </font>
          </li>
        </ul>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">m_Log.Debug( <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"This
is my log message"</span> )</span>
          </p>
        </blockquote>
        <ul>
          <li>
            <div class="MsoNormal">
              <span lang="EN-GB">Add this to your App.config configuration
file.</span>
            </div>
          </li>
        </ul>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p class="CCodeBlock">
            <span lang="EN-GB">
              <font face="Courier New" size="1">&lt;?xml version="1.0" encoding="utf-8"
?&gt;<br />
&lt;configuration&gt; 
<br />
  &lt;configSections&gt;<br />
    &lt;section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"
/&gt;<br />
  &lt;/configSections&gt;<br />
  &lt;log4net&gt;<br />
    &lt;appender name="FileAppender" type=" log4net.Appender.FileAppender"&gt;<br />
      &lt;file value="MyApp.log" /&gt;<br />
      &lt;layout type="log4net.Layout.PatternLayout"&gt;<br />
        &lt;conversionPattern value="%date [%thread]
%-5level %logger {%identity} - %message%newline" /&gt; 
<br />
      &lt;/layout&gt;<br />
    &lt;/appender&gt;<br />
    &lt;root&gt;<br />
      &lt;level value="ALL" /&gt;<br />
      &lt;appender-ref ref="FileAppender" /&gt;<br />
    &lt;/root&gt;<br />
  &lt;/log4net&gt; 
<br />
&lt;/configuration&gt;</font>
            </span>
            <font color="#000000">
              <font face="Courier New">
                <span lang="EN-GB">
                </span>
              </font>
            </font>
          </p>
        </blockquote>
        <p class="MsoNormal">
          <span lang="EN-GB">When you execute your application you will see a new file in the
same directory as the executable called 'MyApp.log'. It will contain an entry similar
to this: </span>
        </p>
        <p class="CCodeBlock">
          <font face="Courier New">
            <span lang="EN-GB">2006-10-12 14:00:10,883 [18076] DEBUG
MyNamespace.MyClass {} – This is my log message</span>
          </font>
        </p>
        <p class="MsoNormal">
          <span lang="EN-GB">The full manual is available at </span>
          <span lang="EN-GB">
            <a href="javascript:ol('http://logging.apache.org/log4net/release/manual/introduction.html');">http://logging.apache.org/log4net/release/manual/introduction.html</a>
          </span>
          <span lang="EN-GB"> and
there are many examples of different configuration options at </span>
          <span lang="EN-GB">
            <a href="javascript:ol('http://logging.apache.org/log4net/release/manual/configuration.html');">http://logging.apache.org/log4net/release/manual/configuration.html</a>
          </span>
          <span lang="EN-GB">
          </span>
        </p>
        <h1 style="TEXT-INDENT: 0cm">
          <a name="_Toc166039472">
            <span lang="EN-GB">Notes</span>
          </a>
        </h1>
        <p class="MsoNormal">
          <span lang="EN-GB">The <a href="http://logging.apache.org/log4net/release/faq.html#naming">recommendation</a> is
to create a static member variable containing the logger object for each class where
you want to log output. The logger will be obtained using the <font face="Courier New">LogManager.GetLogger(type)</font> method
passing in the class's type.</span>
        </p>
        <p class="MsoNormal">
          <span lang="EN-GB">The easiest way to get up and running and initialise log4net is
to call </span>
          <span>
            <font face="Courier New">XmlConfigurator.Configure()</font>.
However, any changes made to the config file whilst the application is running won't
be re-read. If this is desirable the log4net config file can be placed in a separate
file and the <font face="Courier New">ConfigureAndWatch()</font> method can be used
instead. <span lang="EN-GB"><a href="javascript:ol('http://logging.apache.org/log4net/release/faq.html%23config-reload');">http://logging.apache.org/log4net/release/faq.html#config-reload</a></span></span>
        </p>
        <p class="MsoNormal">
          <span lang="EN-GB">The easiest way to add the log to a class is to use <a href="http://www.jetbrains.com/resharper/features/codeTemplate.html">Resharper</a> live
templates. Create a template with the abbreviation 'log' and use the following for
the template text:</span>
        </p>
        <span lang="EN-GB">
          <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
            <p>
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">readonly</span> ILog
m_Log <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> LogManager.GetLogger(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span> ($TYPE$));</span>
            </p>
          </blockquote>
        </span>
        <p class="MsoNormal">
          <span lang="EN-GB">
            <font face="Courier New">$TYPE$</font> is a template variable that
will get its value from the name of the class where the line of code will be placed.</span>
        </p>
        <p class="MsoNormal">
          <span lang="EN-GB">Once setup, you can create a logger by typing <font face="Courier New">log</font> and
pressing tab.</span>
        </p>
        <img width="0" height="0" src="http://www.inaneramblings.com/aggbug.ashx?id=3cb60877-5d0c-4f3e-82a2-60f580025f8f" />
      </body>
      <title>Using log4net</title>
      <guid isPermaLink="false">http://www.inaneramblings.com/PermaLink,guid,3cb60877-5d0c-4f3e-82a2-60f580025f8f.aspx</guid>
      <link>http://www.inaneramblings.com/PermaLink,guid,3cb60877-5d0c-4f3e-82a2-60f580025f8f.aspx</link>
      <pubDate>Thu, 10 May 2007 07:20:20 GMT</pubDate>
      <description>&lt;p&gt;
In any non-trivial project, especially when the application is split across several
tiers, I find adding a few logging statements has a real benefit. I have used &lt;a href="http://logging.apache.org/log4net/"&gt;log4net&lt;/a&gt; in
the last four enterprise-level projects I've worked on and it is a marked improvement
on the standard System.Diagnostics.Trace and Debug classes.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;log4Net is an open source logging tool that allows all aspects of
logging to be modified by changing the&amp;nbsp;config file, which can be done after the
code has been built and is in production. This config file controls which messages
are logged, the format of messages and where log messages are sent. &lt;/span&gt;&lt;span lang=EN-GB style="COLOR: windowtext"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;For example, once the application is in production you may decide
to have certain messages, for example errors and warnings,&amp;nbsp;emailed to the developer
and system admin whilst all other informational messages are logged to a text file.
(This is the approach I used for &lt;a href="http://www.partyhandbook.co.uk/"&gt;PartyHandbook&lt;/a&gt;&amp;nbsp;so
I get immediate notification when an exception is thrown or a warning generated).
Setting this up is just a matter of adding a few lines to the config file and can
be configured such that the application doesn't even need a restart. See &lt;a href="javascript:ol('http://logging.apache.org/log4net/release/config-examples.html%23smtpappender');"&gt;http://logging.apache.org/log4net/release/config-examples.html#smtpappender&lt;/a&gt; for
details of the email appender. &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;The logging facilities are also useful in tracking down specific
bugs in the live system. Imagine&amp;nbsp;&lt;/span&gt;you have a system&amp;nbsp;performing complicated
calculat&lt;span lang=EN-GB&gt;ions and you've received a report that the resulting&amp;nbsp;value&amp;nbsp;is
not as you'd expect. Assuming sufficient logging has been placed in the application,
this would be as simple as turning on 'Debug' level log messages for the &lt;font face="Courier New"&gt;MyProduct.ServerServices.ComplicatedCalculationModule&lt;/font&gt; and
we would see the calculation steps for the live system without having to recreate
the data and start the debugger up.&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;It does take a bit of practice to get into the habit of adding log
statements in the right places and in sufficient quantity to provide the required
level of verbosity but they can prove very useful in diagnosing problems and also
providing another level of documentation to the code. &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;The areas I tend to add logging statements are:&lt;/span&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=Bulleted&gt;
&lt;span lang=EN-GB&gt;In top-level exception handlers. E.g. in Global.asax Page_Error method
or in a try catch block wrapped around the Application.Run statement in the static
Main method of a windows application or service.&lt;/span&gt; 
&lt;li class=Bulleted&gt;
&lt;span lang=EN-GB&gt;&lt;/span&gt;&lt;span lang=EN-GB&gt;In security authentication code to log failed
login attempts&lt;/span&gt; 
&lt;li&gt;
&lt;div class=Bulleted&gt;&lt;span lang=EN-GB&gt;In session handling code to determine when web
sessions or nhibernate sessions are started and stopped&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div class=Bulleted&gt;&lt;span lang=EN-GB&gt;To record configuration settings read in from
the config file (e.g. the database connection string used)&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div class=Bulleted&gt;&lt;span lang=EN-GB&gt;To record things that happen across process boundaries.
E.g. web service messages that are sent and received&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div class=Bulleted&gt;&lt;span lang=EN-GB&gt;User actions. E.g. when user runs a system command
by selecting a menu option or clicking a toolbar button.&lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;Several other open source tools such as nHibernate also uses log4net
to record a whole host of useful information regarding database persistence (E.g.
the SQL statements are being sent to the database) so they can be configured in a
similar manner.&lt;/span&gt;
&lt;/p&gt;
&lt;h1 style="TEXT-INDENT: 0cm"&gt;&lt;a name=_Toc166039471&gt;&lt;span lang=EN-GB&gt;Getting Started&lt;/span&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;This is a 30 second guide to using log4net in a project.&lt;/span&gt;&lt;span lang=EN-GB&gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=MsoNormal&gt;&lt;span lang=EN-GB&gt;Get hold of log4net.dll. This can be downloaded
from &lt;/span&gt;&lt;span lang=EN-GB&gt;&lt;a href="javascript:ol('http://logging.apache.org/log4net/downloads.html');"&gt;http://logging.apache.org/log4net/downloads.html&lt;/a&gt;&lt;/span&gt;&lt;span lang=EN-GB&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div class=MsoNormal&gt;&lt;span lang=EN-GB&gt;Add a reference to the DLL from your project&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div class=MsoNormal&gt;&lt;span lang=EN-GB&gt;Add the following line as the first line in
your application (in the Main( ) method for windows applications or in your global.asax
file): &lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;XmlConfigurator.Configure();&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div class=MsoNormal&gt;&lt;span lang=EN-GB&gt;Add the following line to the top of the class
you'd like to log:&lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;font size=2&gt;&lt;font color=#20879c&gt;&lt;font face="Courier New"&gt;&lt;span lang=EN-GB&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;readonly&lt;/span&gt; ILog
m_Log &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; LogManager.GetLogger( &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(MyClass)
); &lt;/span&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/blockquote&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div class=MsoNormal&gt;&lt;span lang=EN-GB&gt;Add logging statements to your code:&lt;/span&gt;
&lt;/div&gt;
&lt;font size=2&gt;&lt;font color=#20879c&gt;&lt;font face="Courier New"&gt;&lt;span lang=EN-GB&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;m_Log.Debug( &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"This
is my log message"&lt;/span&gt; )&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;ul&gt;
&gt;&gt;&gt;&gt; 
&lt;li&gt;
&lt;div class=MsoNormal&gt;&lt;span lang=EN-GB&gt;Add this to your App.config configuration file.&lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=CCodeBlock&gt;
&lt;span lang=EN-GB&gt;&lt;font face="Courier New" size=1&gt;&amp;lt;?xml version="1.0" encoding="utf-8"
?&amp;gt;&lt;br&gt;
&amp;lt;configuration&amp;gt; 
&lt;br&gt;
&amp;nbsp; &amp;lt;configSections&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"
/&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/configSections&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;log4net&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;appender name="FileAppender" type=" log4net.Appender.FileAppender"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;file value="MyApp.log" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;layout type="log4net.Layout.PatternLayout"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;conversionPattern value="%date [%thread]
%-5level %logger {%identity} - %message%newline" /&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/layout&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/appender&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;root&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;level value="ALL" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;appender-ref ref="FileAppender" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/root&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/log4net&amp;gt; 
&lt;br&gt;
&amp;lt;/configuration&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;font color=#000000&gt;&lt;font face="Courier New"&gt;&lt;span lang=EN-GB&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;When you execute your application you will see a new file in the
same directory as the executable called 'MyApp.log'. It will contain an entry similar
to this: &lt;/span&gt;
&lt;/p&gt;
&lt;p class=CCodeBlock&gt;
&lt;font face="Courier New"&gt;&lt;span lang=EN-GB&gt;2006-10-12 14:00:10,883 [18076] DEBUG MyNamespace.MyClass
{} – This is my log message&lt;/span&gt; &lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;The full manual is available at &lt;/span&gt;&lt;span lang=EN-GB&gt;&lt;a href="javascript:ol('http://logging.apache.org/log4net/release/manual/introduction.html');"&gt;http://logging.apache.org/log4net/release/manual/introduction.html&lt;/a&gt;&lt;/span&gt;&lt;span lang=EN-GB&gt; and
there are many examples of different configuration options at &lt;/span&gt;&lt;span lang=EN-GB&gt;&lt;a href="javascript:ol('http://logging.apache.org/log4net/release/manual/configuration.html');"&gt;http://logging.apache.org/log4net/release/manual/configuration.html&lt;/a&gt;&lt;/span&gt;&lt;span lang=EN-GB&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;h1 style="TEXT-INDENT: 0cm"&gt;&lt;a name=_Toc166039472&gt;&lt;span lang=EN-GB&gt;Notes&lt;/span&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p class=MsoNormal&gt;
&lt;span lang=EN-GB&gt;The &lt;a href="http://logging.apache.org/log4net/release/faq.html#naming"&gt;recommendation&lt;/a&g