Friday, August 21, 2009

XML Configuration File Upgrade Technique

One of my colleagues asked me if there was a simple way to upgrade an xml configuration to one conforming to a new schema. Actually this is pretty easy and fun in .NET (if we use DataSets).
Here is an example

Old schema – OldEmployee.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="EmployeeDetails">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="Employee">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Name" type="xs:string" />
              <xs:element name="Designation" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

New Schema – NewEmployee.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="EmployeeDetails">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="Employee">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Name" type="xs:string" />
              <xs:element name="Designation" type="xs:string" />
              <xs:element name="Age" type="xs:positiveInteger" default="40"/>
              <xs:element name="Gender" type="xs:string" default="Male"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
The following code

  • Reads the old schema into a data set
  • Reads the old XML file (conforming to the old schema)
  • Reads the new schema into a new data set
  • Performs a merge on the new data set merging the old dataset
  • Outputs the upgraded XML configuration file
using System.Data;

namespace ConfigFileUpgrade
{
   class Program
   {
      static void Main(string[] args)
      {
         DataSet dsOld = new DataSet();
         dsOld.ReadXmlSchema("OldEmployee.xsd");
         // Now lets try to read an XML conforming to this schema
         dsOld.ReadXml("OldEmployee.xml", XmlReadMode.Auto);

         // We create a new dataset and assign the new schema to it
         // This data set will not contain any data since we have read only the schema
         DataSet dsNew = new DataSet();
         dsNew.ReadXmlSchema("NewEmployee.xsd");

         // We merge the old data set with the new data
         // all the data in the old data set now gets merged to the new data set with
         // the new schema
         dsNew.Merge(dsOld, false, MissingSchemaAction.Add);

         // Upgrade is complete
         dsNew.WriteXml("NewEmployee.xml");
      }
   }
}

Thursday, August 20, 2009

Increasing performance (.NET Regular Expressions)

I just discovered that the .NET Regex class offers a static method (CompileToAssembly) to compile a regular expression to an assembly for increased performance. Here is a sample code.
using System;
using System.Text.RegularExpressions;
using System.Reflection;

namespace CompiledRegEx
{
   class Program
   {
      static void Main(string[] args)
      {
         if ( args.Length < 5 )
         {
            Console.WriteLine("Error: Insufficient Parameters. \nUsage: rexc ");
            return;
         }

         string pattern = args[0];
         string options = args[1];
         string className = args[2];
         string namespaceName = args[3];
         string assemblyName = args[4];

         RegexCompilationInfo ri = new RegexCompilationInfo(pattern,
            (RegexOptions)Convert.ToInt32(options),
            className,
            namespaceName,
            true);

         Regex.CompileToAssembly(new RegexCompilationInfo[] { ri },
            new AssemblyName(assemblyName));

         Console.WriteLine("Regular Expression successfully compiled to an assembly");
      }
   }
}
You can now use the new type from the compiled assembly just as you would use any other type from an assembly. The Match method of the new RegEx type does not take the pattern as a parameter. If you use a lot of static regular expressions in your code, this can provide significant gain in performance.

Monday, August 17, 2009

Auto and Manual Reset Events Revisited

Just posted as article for Code Project on Auto and Manual Reset Events. I ended up writing this article after my bitter experience with analyzing some other group's log files and finding out the problem in their code was due to improper use of Manual Reset events.

Click HERE to read the article at CodeProject.

Type Safe Logging in C++

My Friend Vivek and I authored an article for Code Project. It is about Type Safe Logging in C++.

Sunday, August 16, 2009

WPF data Binding using Custom Expressions

I was searching the web for some information about how to perform WPF data Binding using custom expressions. I came across an excellent article that explains this.

Here is the link: http://www.11011.net/wpf-binding-expressions