107
Chapter 7
Saving and Restoring Data
After completing this chapter, you will be able to:
Export a DataSet to a file in XML format
Import a previously exported DataSet from XML format
Define the structure of the exported XML content
Access the XSD schema for a DataSet or DataTable
ADO.NET isn’t the only popular format for managing data in .NET applications. XML—content
crafted using the Extensible Markup Language—is another common format that provides
standardized, cross-platform data management in a semi-human-readable format.
The DataSet class and the DataTable instances contained within it include features for moving
data back and forth between ADO.NET and XML. This chapter demonstrates those features,
focusing on the ability to serialize the contents of a DataSet for later use, either by loading
it into another DataSet or by accessing the data directly through some other XML-enabled
application. ADO.NET includes full schema definition support using Schema Definition
Language (XSD).
Note
Before version 4, ADO.NET included an XmlDataDocument class that supported on-demand
synchronization between the contents of a DataSet and an XML document. That class has
since been deprecated. You can simulate some of the functionality formerly available through
XmlDataDocument using the features discussed in this chapter. You can also use DataSet–focused
LINQ queries, as discussed in Chapter 18, “Using LINQ to DataSet,” as a substitute for the obso-
lete XmlDataDocument class.
Serializing
DataSet
and
DataTable
Objects
ADO.NET was designed with XML in mind, so generating XML content from a DataSet takes
very little effort. Reading XML content into a DataSet is even easier because ADO.NET will
guess at the correct structure of the data even if you don’t provide table design guidance.
Dwonloaded from: iDATA.ws
108
Microsoft ADO.NET 4 Step by Step
Writing XML
To generate XML for the data content of an existing DataSet instance, call its WriteXml method,
passing an output file name.
C#
DataSet infoSet = new DataSet();
// ----- Add tables, relations, and data, then call...
infoSet.WriteXml(@"c:\StorageFile.xml");
Visual Basic
Dim infoSet As New DataSet
' ----- Add tables, relations, and data, then call...
infoSet.WriteXml("c:\StorageFile.xml")
In addition to file names, various overloads of WriteXml accept a valid Stream instance, a
TextWriter instance, or an XmlWriter instance as their first argument. The generated XML is
straightforward, using table and column names to define each element tag. Here is some
typical XML data content produced by WriteXml. This content includes three customer
data rows, each with four fields: a string column (BusinessName), two numeric fields (ID,
AnnualFee), and a date value (ContractDate) in UTC format with a time zone offset.
<CustomerDataSet>
<Customer>
<ID>1</ID>
<BusinessName>City Power & Light</BusinessName>
<AnnualFee>500</AnnualFee>
<ContractDate>2008-06-01T00:00:00-07:00</ContractDate>
</Customer>
<Customer>
<ID>2</ID>
<BusinessName>Lucerne Publishing</BusinessName>
<AnnualFee>300</AnnualFee>
<ContractDate>2008-01-01T00:00:00-08:00</ContractDate>
</Customer>
<Customer>
<ID>3</ID>
<BusinessName>Southridge Video</BusinessName>
<AnnualFee>350</AnnualFee>
<ContractDate>2010-02-15T00:00:00-08:00</ContractDate>
</Customer>
</CustomerDataSet>
Dwonloaded from: iDATA.ws
Chapter 7 Saving and Restoring Data
109
By default, WriteXml writes XML for only the data rows in each table; the method saves no
information about the structure of the DataSet. To include the DataSet object’s schema defi-
nition along with the data, add a second argument to the WriteXml method call, passing
XmlWriteMode.WriteSchema.
C#
infoSet.WriteXml(targetFile, XmlWriteMode.WriteSchema);
Visual Basic
infoSet.WriteXml(targetFile, XmlWriteMode.WriteSchema)
Other XmlWriteMode enumeration members include IgnoreSchema (don’t include the schema,
which is the same as leaving off the second argument) and DiffGram (a special format that
outputs differences between the Original and the Current versions of each DataRow within
the DataSet).
If you want to output only the schema, use the DataSet object’s WriteXmlSchema method,
passing it a file name, a Stream, a TextWriter, or an XmlWriter.
C#
infoSet.WriteXmlSchema(targetSchemaFile);
Visual Basic
infoSet.WriteXmlSchema(targetSchemaFile)
The DataTable class also includes WriteXml and WriteXmlSchema methods that you can use
to generate XML content on a table-by-table basis. In addition to the file/stream/writer tar-
get and the XmlWriteMode arguments, the DataTable versions of these methods accept an
optional Boolean argument that indicates whether child tables linked via DataRelation ob-
jects should be sent to the output with the instantiating table’s schema or data. You can use
this Boolean argument either after or instead of the XmlWriteMode argument.
C#
// ----- Write the customer data AND the linked order data.
customers.WriteXml(targetFile, true);
Visual Basic
' ----- Write the customer data AND the linked order data.
customers.WriteXml(targetFile, True)
Dwonloaded from: iDATA.ws
110
Microsoft ADO.NET 4 Step by Step
If you want to keep the XML content in the application, the DataSet class includes GetXml
and GetXmlSchema methods that return string documents with content similar to the output
of the WriteXml and WriteXmlSchema methods. The DataTable.GetDataTableSchema method
returns the XSD for a table in plain string format.
Reading XML
Both the DataSet and DataTable classes include ReadXml and ReadXmlSchema counterparts
to the XML-writing methods. To use them, create a new DataSet or DataTable instance; then
call the appropriate method, passing a file name, a Stream, a TextReader, or an XmlReader.
C#
DataSet infoSet = new DataSet();
// ----- To read the schema, use...
infoSet.ReadXmlSchema(@"c:\StorageSchemaFile.xml");
// ----- To read the data, use...
infoSet.ReadXml(@"c:\StorageFile.xml");
Visual Basic
Dim infoSet As New DataSet
' ----- To read the schema, use...
infoSet.ReadXmlSchema("c:\StorageSchemaFile.xml")
' ----- To read the data, use...
infoSet.ReadXml("c:\StorageFile.xml")
A second argument to the DataSet.ReadXml method lets you indicate how the incoming
content should be processed. It uses one of the following enumerated values:
XmlReadMode.Auto Lets ReadXml figure out what to do with the incoming content
automatically. If it detects a valid schema with the data, it processes the schema before
loading the data. If it sees a DiffGram, it interprets it appropriately. This is the default
option if you don’t add the read-mode argument.
XmlReadMode.ReadSchema Reconstructs the DataTable members of the DataSet
without loading in the data.
Dwonloaded from: iDATA.ws
Chapter 7 Saving and Restoring Data
111
XmlReadMode.IgnoreSchema Loads in the data, ignoring any schema that might be
included in the XML. Instead, the existing DataSet structure is used.
XmlReadMode.InferSchema Builds a new schema based on the structure of the XML
data alone, ignoring any included schema. If needed, any existing DataSet structure will
be augmented with new schema information.
XmlReadMode.DiffGram Reads in the content previously written with the WriteXml
method’s XmlWriteMode.DiffGram mode.
XmlReadMode.Fragment Reads in and processes XML content that might be partial
or incomplete.
XmlReadMode.InferTypedSchema Similar to the InferSchema mode, but ReadXml
will go out of its way to figure out the data type of each incoming data column.
ReadXml or ReadXmlSchema support both inline and linked XSD structure definitions.
DataSet includes an additional InferXmlSchema method. It works just like the ReadXmlSchema
method, but you can pass it an array of namespace names to exclude on import.
Guiding XML Generation
The Read... and Write... XML methods generate valid XML that can be used right away with
any XML tools. Still, the default format might be insufficient for your processing needs. That’s
why ADO.NET includes features that let you guide and enhance the XML generation process.
There are three main types of guidance you can provide to the XML content: namespace
identification, child table nesting, and column management.
Identifying Namespaces
XML includes a namespace feature that lets you group content by purpose, even among tags
that appear within the same parent element. Three ADO.NET classes—DataSet, DataTable,
and DataColumn—include properties that let you assign both the namespace and the
namespace prefix that will appear in the XML tags associated with the table and column
values.
Dwonloaded from: iDATA.ws