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 reads 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.
|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 accept 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 Deriving 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 columns to existing tables. Extra tables will not be added if there are not 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 "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.|
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.
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 StringReader.
Dim dataSet As DataSet = New DataSet dataSet.ReadXml("input.xml", XmlReadMode.ReadSchema)
DataSet dataSet = new DataSet(); dataSet.ReadXml("input.xml", XmlReadMode.ReadSchema);
Dim dataSet As DataSet = New DataSet Dim dataTable As DataTable = New DataTable("table1") dataTable.Columns.Add("col1", Type.GetType("System.String")) dataSet.Tables.Add(dataTable) 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) dataSet.ReadXml(xmlSR, XmlReadMode.IgnoreSchema)
DataSet dataSet = new DataSet(); DataTable dataTable = new DataTable("table1"); dataTable.Columns.Add("col1", typeof(string)); dataSet.Tables.Add(dataTable); string xmlData = "<XmlDS><table1><col1>Value1</col1></table1><table1><col1>Value2</col1></table1></XmlDS>"; System.IO.StringReader xmlSR = new System.IO.StringReader(xmlData); dataSet.ReadXml(xmlSR, XmlReadMode.IgnoreSchema);
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 BeginLoadData method for each table in the DataSet, and then call ReadXml. Finally, call EndLoadData for each table in the DataSet, as shown in the following example.
Dim dataTable As DataTable For Each dataTable In dataSet.Tables dataTable.BeginLoadData() Next dataSet.ReadXml("file.xml") For Each dataTable in dataSet.Tables dataTable.EndLoadData() Next
foreach (DataTable dataTable in dataSet.Tables) dataTable.BeginLoadData(); dataSet.ReadXml("file.xml"); foreach (DataTable dataTable in dataSet.Tables) dataTable.EndLoadData();
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="customDataSet" elementFormDefault="qualified" targetNamespace="http://www.tempuri.org/customDataSet.xsd" xmlns="http://www.tempuri.org/customDataSet.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.