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");
      }
   }
}

No comments:

Post a Comment