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