Loading a DataSet from XML

The contents of an ADO.NET DataSet can be created from an XML stream or document. In addition, with the .NET Framework you have great flexibility over what information is loaded from XML, and how the schema or relational structure of the DataSet is created.

To fill a DataSet with data from XML, use the ReadXml method of the DataSet object. The ReadXml method will read from a file, a stream, or an XmlReader, and takes as arguments the source of the XML plus an optional XmlReadMode argument. (For more information about the XmlReader, see Reading XML Data with XmlTextReader.) The ReadXml method reads the contents of the XML stream or document and loads the DataSet with data. It will also create the relational schema of the DataSet depending on the XmlReadMode specified and whether or not a relational schema already exists.

The following table describes the options for the XmlReadMode argument.

XmlReadMode Description
Auto This is the default. Examines the XML and chooses the most appropriate option in the following order:
  • If the XML is a DiffGram, DiffGram is used.
  • If the DataSet contains a schema or the XML contains an inline schema, ReadSchema is used.
  • If the DataSet does not contain a schema and the XML does not contain an inline schema, InferSchema is used.

If you know the format of the XML being read, for best performance it is recommended that you set an explicit XmlReadMode rather than allowing the Auto default.

ReadSchema Reads any inline schema and loads the data and schema.

If the DataSet already contains a schema, new tables are added from the inline schema to the existing schema in the DataSet. If any tables in the inline schema already exist in the DataSet, an exception is thrown. You will not be able to modify the schema of an existing table using XmlReadMode.ReadSchema.

If the DataSet does not contain a schema, and there is no inline schema, no data is read.

Inline schema can be defined using XML Schema definition language (XSD) schema. For details about writing inline schema as XML Schema, see Generating DataSet Relational Structure from XML Schema (XSD).

IgnoreSchema Ignores any inline schema and loads the data into the existing DataSet schema. Any data that does not match the existing schema is discarded. If no schema exists in the DataSet, no data is loaded.

If the data is a DiffGram, IgnoreSchema has the same functionality as DiffGram.

InferSchema Ignores any inline schema and infers the schema per the structure of the XML data, then loads the data.

If the DataSet already contains a schema, the current schema is extended by adding new tables where there is no existing table, or by adding columns to existing tables. An exception is thrown if an inferred table already exists with a different namespace, or if any inferred columns conflict with existing columns.

For details about how ReadXmlSchema infers a schema from an XML document, see Inferring DataSet Relational Structure from XML.

DiffGram Reads a DiffGram and adds the data to the current schema. DiffGram merges new rows with existing rows where the unique identifier values match. See the note on "Merging Data from XML" at the end of this topic. For more information about DiffGrams, see DiffGrams.
Fragment Continues reading multiple XML fragments until the end of the stream is reached. Fragments that match the DataSet schema are appended to the appropriate tables. Fragments that do not match the DataSet schema are discarded.

**Note   **If you pass an XmlReader to ReadXml that is positioned part of the way into an XML document, ReadXml will read to the next element node and will treat that as the root element, reading until the end of the element node only. This does not apply if you specify XmlReadMode.Fragment.

DTD Entities

If your XML contains entities defined in a document type definition (DTD) schema, an exception will be thrown if you attempt to load a DataSet by passing a file name, stream, or non-validating XmlReader to ReadXml. Instead, you must create an XmlValidatingReader, with EntityHandling set to EntityHandling.ExpandEntities, and pass your XmlValidatingReader to ReadXml. The XmlValidatingReader will expand the entities prior to being read by the DataSet.

The following code examples show how to load a DataSet from an XML stream. The first example shows a file name being passed to the ReadXml method. The second example shows a string that contains XML being loaded using a System.IO.StringReader.

Dim myDS As DataSet = New DataSet
myDS.ReadXml("input.xml", XmlReadMode.ReadSchema)
[C#]
DataSet myDS = new DataSet();
myDS.ReadXml("input.xml", XmlReadMode.ReadSchema);
[Visual Basic]
Dim myDS As DataSet = New DataSet
Dim myTable As DataTable = New DataTable("table1")
myTable.Columns.Add("col1", Type.GetType("System.String"))
myDS.Tables.Add(myTable)

Dim xmlData As String = "<XmlDS><table1><col1>Value1</col1></table1><table1><col1>Value2</col1></table1></XmlDS>"

Dim xmlSR As System.IO.StringReader = New System.IO.StringReader(xmlData)

myDS.ReadXml(xmlSR, XmlReadMode.IgnoreSchema)
[C#]
DataSet myDS = new DataSet();
DataTable myTable = new DataTable("table1");
myTable.Columns.Add("col1", typeof(string));
myDS.Tables.Add(myTable);

string xmlData = "<XmlDS><table1><col1>Value1</col1></table1><table1><col1>Value2</col1></table1></XmlDS>";

System.IO.StringReader xmlSR = new System.IO.StringReader(xmlData);

myDS.ReadXml(xmlSR, XmlReadMode.IgnoreSchema);

Note   If you call ReadXml to load a very large file, you may encounter slow performance. To ensure best performance for ReadXml, on a large file, call the DataTable.BeginLoadData method for each table in the DataSet, then call ReadXml. Finally, call DataTable.EndLoadData for each table in the DataSet as shown in the following example.

Dim t As DataTable

For Each t In ds.Tables
  t.BeginLoadData()
Next

ds.ReadXml("file.xml")

For Each t in ds.Tables
  t.EndLoadData()
Next
[C#]
foreach (DataTable t in ds.Tables)
  t.BeginLoadData();

ds.ReadXml("file.xml"); 

foreach (DataTable t in ds.Tables)
  t.EndLoadData();

Note   If the XSD schema for your DataSet includes a targetNamespace, data may not be read, and you may encounter exceptions, when calling ReadXml to load the DataSet with XML that contains elements with no qualifying namespace. To read unqualified elements in this case, set elementFormDefault equal to "qualified" in your XSD schema. For example:

<xsd:schema id="MyDataSet" 
  elementFormDefault="qualified"
  targetNamespace="http://www.tempuri.org/MyDataSet.xsd" 
  xmlns="http://www.tempuri.org/MyDataSet.xsd" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
</xsd:schema>

Merging Data from XML

If the DataSet already contains data, the new data from the XML is added to the data already present in the DataSet. ReadXml does not merge from the XML into the DataSet any row information with matching primary keys. To overwrite existing row information with new information from XML, use ReadXml to create a new DataSet, and then Merge the new DataSet into the existing DataSet. Note that loading a DiffGram using ReadXML with an XmlReadMode of DiffGram will merge rows that have the same unique identifier.

See Also

XML and the DataSet | DiffGrams | Generating DataSet Relational Structure from XML Schema (XSD) | Inferring DataSet Relational Structure from XML | Loading DataSet Schema Information from XML | DataSet.Merge Method | Creating and Using DataSets