|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionLooking pretty sharp kiddo, but your I’m not going to dwell on the pros and cons of typed vs. untyped One of the reasons for the hype behind Let's consider a common situation in today’s development environment: a web service or another process provides an XML document with dozens or hundreds of elements and a developer facing a task of creating a strongly typed XmlDocument doc = new XmlDocument();
doc.Load(@"C:\temp\roster.xml");
DataSet ds = new DataSet();byte [] buf =
System.Text.ASCIIEncoding.ASCII.GetBytes(doc.OuterXml);
System.IO.MemoryStream ms = new System.IO.MemoryStream(buf);
ds.ReadXml(ms,XmlReadMode.InferSchema);ms.Close();
ds.WriteXmlSchema(@"C:\temp\roster.xsd");
Here is a mini version of a sample input XML document: <roster>
<type>demo</type>
<class>12345</class>
<instructor>Waldo Erickson</instructor>
<title>Introduction to .NET</title>
<student>
<grade>P</grade>
<name>Jane Doe</name>
<phone>555-1212</phone>
</student>
<student>
<grade>F</grade>
<name>John Hush</name>
<phone>779-1490</phone>
</student>
</roster>
and what the resulting roster.xsd schema looks like: <?xml version="1.0"?>
<xs:schema id="NewDataSet" targetNamespace="http://tempuri.org/roster.xsd"
xmlns:mstns="http://tempuri.org/roster.xsd"
xmlns="http://tempuri.org/roster.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
attributeFormDefault="qualified"
elementFormDefault="qualified">
<xs:element name="roster">
<xs:complexType>
<xs:sequence>
<xs:element name="type" type="xs:string" minOccurs="0" />
<xs:element name="class" type="xs:string" minOccurs="0" />
<xs:element name="instructor" type="xs:string" minOccurs="0" />
<xs:element name="title" type="xs:string" minOccurs="0" />
<xs:element name="student" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="grade" type="xs:string" minOccurs="0" />
<xs:element name="name" type="xs:string" minOccurs="0" />
<xs:element name="phone" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet"
msdata:IsDataSet="true" msdata:EnforceConstraints="False">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="roster" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Done? Not yet. We created a schema inherited from the XML document, but not a strongly typed Next, let’s use the roster.xsd file within a Visual Studio project and generate a strongly typed Having generated the XML schema and the typed Let’s make life easy. What we really want after all this work is a TypedDataSet tds = new TypedDataSet();tds.Fill(xmlDoc);
OR tds.ReadXml(@”c:\temp\roster.xml”);
One solution is to modify the roster.cs class directly and add the using System;
using System.Data;
using System.Xml;
namespace Rosters{
public class TypedDataSet: roster
{
private TypedDataSet tds;
public void Fill(XmlDocument doc)
{
// First populate an untyped DataSet with the xml document
DataSet ds = new DataSet();
byte [] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(doc.OuterXml);
System.IO.MemoryStream ms = new System.IO.MemoryStream(buf);
ds.ReadXml(ms);
ms.Close();
// Then fill the typed DataSet from the untyped DataSet
Fill(ds);
}
public new void ReadXml(string xmlFile)
{
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(xmlFile);
this.Fill(xmlDoc);
}
catch (XmlException)
{
// ignore or handle exception here
}
public void Fill(DataSet ds)
{
tds = this;
// Map each row of each table in the untyped DataSet to a
// corresponding item in the strongly typed DataSet
for ( int i = 0; i < ds.Tables.Count; i++ )
{
foreach (DataRow iDr in ds.Tables[i].Rows)
{
DataRow oDr = tds.Tables[i].NewRow();
for ( int j = 0; j < ds.Tables[i].Columns.Count; j++ )
try
{
oDr[j] = iDr[j].ToString();
}
catch (NoNullAllowedException)
{
// ignore for now – just in
// case no such column in DataSet
}
tds.Tables[i].Rows.Add(oDr);
}
}
tds.AcceptChanges();
}
}
}
Points of InterestThis example shows one workaround for the occasional
| ||||||||||||||||||||