The XmlDataDocument Class The System.Xml namespace also includes the capability to automatically synchronize a DataSet with an equivalent XML file. The XmlDocument class is useful for working with XML via the DOM, but it's not a data-enabled class. To bring the DataSet class into the picture, you need to use an XmlDataDocument class, which inherits from the XmlDocument class. Table 3.4 shows the additional members that the XmlDataDocument class adds to the XmlDocument class. Table 3.4. Additional Members of the XmlDataDocument ClassMember | Type | Description |
---|
DataSet | Property | Retrieves a DataSet object representing the data in the XmlDataDocument object | GetElementFromRow() | Method | Retrieves an XmlElement object representing a specified DataRow object | GetRowFromElement() | Method | Retrieves a DataRow object representing a specified XmlElement object | Load() | Method | Loads the XmlDataDocument object and synchronizes it with a DataSet object | The XmlDataDocument class enables you to exploit the connections between XML documents and DataSet objects. You can do this by synchronizing the XmlDataDocument object (and, hence, the XML document that it represents) with a particular DataSet object. You can start the synchronization process with the XMLDataDcoument object, a full DataSet object, or a schema-only DataSet object. If you have an XML file in an XmlDataDocument object, you can retrieve a DataSet object from its DataSet property. The following code sample demonstrates this technique: // Create a new XmlTextReader on the file XmlTextReader xtr = new XmlTextReader(@"..\..\Books.xml"); // Create an object to synchronize XmlDataDocument xdd = new XmlDataDocument(); // Retrieve the associated DataSet DataSet ds = xdd.DataSet; // Initialize the DataSet by reading the schema from the XML document ds.ReadXmlSchema(xtr); // Reset the XmlTextReader xtr.Close(); xtr = new XmlTextReader(@"..\..\Books.xml"); // Tell it to ignore whitespace xtr.WhitespaceHandling = WhitespaceHandling.None; // Load the synchronized object xdd.Load(xtr); This code performs some extra setup to make sure that the DataSet object can hold the data from the XmlDataDocument object. Even when you're creating the DataSet object from the XmlDataDocument object, you must still explicitly create the schema of the DataSet object before it will contain data. That's because, in this technique, you can also use a DataSet object that represents only a portion of the XmlDataDocument object. In this case, the code takes advantage of the ReadXmlSchema() method of the DataSet object to automatically construct a schema that matches the XML document. Because the XmlTextReader object is designed for forward-only use, the code closes and reopens this object after reading the schema so that it can also be used to read the data. | When you use the ReadXmlSchema() method of the DataSet object to construct an XML Schema for the DataSet, both elements and attributes within the XML document become DataColumn objects in the DataSet object. |
A second way to end up with a DataSet object synchronized to an XmlDataDocument object is to start with a DataSet object. To use this technique, you simply pass the DataSet object (which you have already filled with data) to the XmlDataDocument object's constructor, as shown in the following code segment: // Fill the DataSet sqlDataAdapter1.Fill(dsEmployees1, "Employees"); // Retrieve the associated document XmlDataDocument xd = new XmlDataDocument(dsEmployees1); The third method of synchronizing the two objects is to follow a three-step process: Create a new DataSet object with the proper schema to match an XML document, but no data. Create the XmlDataDocument object from the DataSet object. Load the XML document into the XmlDataDocument object. One way to manage this is to use an XML Schema file. An XML Schema file describes the format of an XML file. For example, here's an XML Schema description of Books.xml: <?xml version="1.0" encoding="utf-8" ?> <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Books"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="Book"> <xs:complexType> <xs:sequence> <xs:element name="Author" type="xs:string" /> <xs:element name="Title" type="xs:string" /> </xs:sequence> <xs:attribute name="Pages" type="xs:string" /> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> Given this schema file, with a name such as Books.xsd, you can construct the corresponding DataSet by calling the ReadXmlSchema method of a DataSet object and, from there, creating the corresponding XmlDataDocument, as shown in the following code segment: // Create a dataset with the desired schema DataSet ds = new DataSet(); ds.ReadXmlSchema(@"..\..\Books.xsd"); // Create a matching document XmlDataDocument xdd = new XmlDataDocument(ds); // Load the XML xdd.Load(@"..\..\Books.xml"); The advantage of using this technique is that you don't have to represent the entire XML document in the DataSet schema; the schema needs to include only the XML elements that you want to work with. For example, in this case, the DataSet object does not contain the Publisher column, even though the XmlDataDocument includes that column. |