Chapter 12: Working with XML Data

DataSet + XmlDocument = XmlDataDocument

The previous code snippets used some of the DataSet object's XML features, but they weren't terribly exciting. If you're using these features simply to store the contents of a DataSet to a file and later read that data back into your DataSet, the fact that ADO.NET is storing the data as XML is irrelevant.

If you're really interested in working with the contents of a DataSet in XML format, you'll probably want to load the data into an XmlDocument object. This object has a Load method that you can use to load the contents of an XML file, so you could use the DataSet object's WriteXml method to create your XML file and then call the XmlDocument object's Load method to load the file. That might sound fine at first, but you'll have two objects storing the same data and you'll have no simple way to synchronize them. If you want to keep the objects synchronized and you change the contents of one object, you'll need to locate and modify the corresponding data in the other object. What a hassle!

Using the XmlDataDocument Object

The simple solution to this problem is to use an XmlDataDocument object. You can think of an XmlDataDocument as an XmlDocument that knows how to communicate with a DataSet object. The XmlDataDocument class is derived from the XmlDocument class, so an XmlDataDocument object exposes all the same features as an XmlDocument.

The XmlDataDocument object provides two key features. It lets you easily load the contents of a DataSet into an XmlDocument, and vice versa. The XmlDataDocument also synchronizes itself with the DataSet. If the DataSet object contains data, that same data will be available through the XmlDataDocument object. Also, when you change the contents of one object, that change will affect the other.

Accessing Your DataSet as an XML Document

If you're an XML programmer who's used to working with XML documents to access data, you'll find it easy to use the XmlDataDocument object to access the contents of a DataSet through XML interfaces.

For example, you can create an XmlDataDocument synchronized with your DataSet to use XPath queries to examine the contents of the DataSet. The following code snippet creates an XmlDataDocument synchronized with a DataSet that contains order and line item information for a customer. The code then uses XPath queries to extract the contents of an order from the XmlDataDocument object. It uses the FillMyDataSet procedure from previous code snippets and requires you to use the appropriate construct for the language to reference the System.Xml namespace.

Visual Basic .NET

'Add this line of code at the beginning of the code module. Imports System.Xml Dim ds As New DataSet() FillMyDataSet(ds) Dim xmlDataDoc As New XmlDataDocument(ds) Dim nodOrder, nodDetail As XmlNode Dim strXPathQuery As String strXPathQuery = "/NewDataSet/Orders[OrderID=10268]" nodOrder = xmlDataDoc.SelectSingleNode(strXPathQuery) Console.WriteLine("OrderID = " & nodOrder.ChildNodes(0).InnerText) Console.WriteLine("CustomerID = " & nodOrder.ChildNodes(0).InnerText) Console.WriteLine("OrderDate = " & nodOrder.ChildNodes(0).InnerText) Console.WriteLine("Line Items:") strXPathQuery = "/NewDataSet/Order_x0020_Details[OrderID=10268]" For Each nodDetail In xmlDataDoc.SelectNodes(strXPathQuery)     Console.WriteLine(vbTab & "ProductID = " & _                       nodDetail.ChildNodes(1).InnerText)     Console.WriteLine(vbTab & "Quantity = " & _                       nodDetail.ChildNodes(2).InnerText)     Console.WriteLine(vbTab & "UnitPrice = " & _                       nodDetail.ChildNodes(3).InnerText)     Console.WriteLine() Next nodDetail

Visual C# .NET

//Add this line of code at the beginning of the code module. using System.Xml; DataSet ds = new DataSet(); FillMyDataSet(ds); XmlDataDocument xmlDataDoc = new XmlDataDocument(ds); XmlNode nodOrder; string strXPathQuery; strXPathQuery = "/NewDataSet/Orders[OrderID=10268]"; nodOrder = xmlDataDoc.SelectSingleNode(strXPathQuery); Console.WriteLine("OrderID = " + nodOrder.ChildNodes[0].InnerText); Console.WriteLine("CustomerID = " +                    nodOrder.ChildNodes[1].InnerText); Console.WriteLine("OrderDate = " + nodOrder.ChildNodes[2].InnerText); Console.WriteLine("Line Items:"); strXPathQuery = "/NewDataSet/Order_x0020_Details[OrderID=10268]"; foreach (XmlNode nodDetail in xmlDataDoc.SelectNodes(strXPathQuery)) {     Console.WriteLine("\tProductID = " +                        nodDetail.ChildNodes[1].InnerText);     Console.WriteLine("\tQuantity = " +                        nodDetail.ChildNodes[2].InnerText);     Console.WriteLine("\tUnitPrice = " +                       nodDetail.ChildNodes[3].InnerText);     Console.WriteLine(); }

Caching Updates to the XML Document

Earlier in the chapter, I pointed out that XML documents don't maintain state in a way that lets you later submit changes to your database. The XmlDataDocument object actually provides this functionality by synchronizing the XML document and the DataSet. As you modify the contents of the XML document, the XmlDataDocument object modifies the corresponding data in the DataSet object. The DataSet object then has all the information it needs to submit the change to the database.

The following code snippet demonstrates this functionality. The code uses an XPath query to locate an order and modifies the contents of the child node that corresponds to the CustomerID for the order. The code then examines the contents of the corresponding DataRow to show that both the current and original values for the order's CustomerID are available in the DataRow. You can use a DataAdapter with the necessary updating logic to submit this change to your database.

Just before modifying the contents of the XML document, the code sets the EnforceConstraints property of the DataSet object to False. Without this line of code, the snippet would generate an exception. You will receive an error if you modify the contents of an XML document using the XmlDataDocument object if the DataSet associated with the XmlDataDocument has its EnforceConstraints property set to True.

Visual Basic .NET

'Add this line of code at the beginning of the code module. Imports System.Xml Dim ds As New DataSet() FillMyDataSet(ds) Dim tblOrders As DataTable = ds.Tables("Orders") tblOrders.PrimaryKey = New DataColumn() _                        {tblOrders.Columns("OrderID")} Dim xmlDataDoc As New XmlDataDocument(ds) Dim nodOrder, nodDetail As XmlNode Dim strXPathQuery As String = "/NewDataSet/Orders[OrderID=10268]" nodOrder = xmlDataDoc.SelectSingleNode(strXPathQuery) ds.EnforceConstraints = False nodOrder.ChildNodes(1).InnerText = "ALFKI" ds.EnforceConstraints = True Dim row As DataRow = tblOrders.Rows.Find(10268) Console.WriteLine("OrderID = " & row("OrderID")) Console.WriteLine(vbTab & "Current  CustomerID = " & _                   row("CustomerID")) Console.WriteLine(vbTab & "Original CustomerID = " & _                   row("CustomerID", DataRowVersion.Original))

Visual C# .NET

//Add this line of code at the beginning of the code module. using System.Xml; DataSet ds = new DataSet(); FillMyDataSet(ds); DataTable tblOrders = ds.Tables["Orders"]; tblOrders.PrimaryKey = new DataColumn[]                         {tblOrders.Columns["OrderID"]}; XmlDataDocument xmlDataDoc = new XmlDataDocument(ds); XmlNode nodOrder, nodDetail; string strXPathQuery = "/NewDataSet/Orders[OrderID=10268]"; nodOrder = xmlDataDoc.SelectSingleNode(strXPathQuery); ds.EnforceConstraints = false; nodOrder.ChildNodes[1].InnerText = "ALFKI"; ds.EnforceConstraints = true; DataRow row = tblOrders.Rows.Find(10268); Console.WriteLine("OrderID = " + row["OrderID"]); Console.WriteLine("\tCurrent  CustomerID = " + row["CustomerID"]); Console.WriteLine("\tOriginal CustomerID = " +                   row["CustomerID", DataRowVersion.Original]);

As you can see, the changes are now cached in the DataSet. We could then use a DataAdapter to submit those cached changes back to the database.



Microsoft ADO. NET Core Reference
Microsoft ADO.NET (Core Reference) (PRO-Developer)
ISBN: 0735614237
EAN: 2147483647
Year: 2002
Pages: 104
Authors: David Sceppa

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net