Working with the XmlDataDocument Object


The DataSet provides an excellent vehicle for transferring data from one or more relational-style rowsets to XML documents and XML schemas, and vice versa. But you can do even better if you are predominantly concerned with accessing data as XML, rather than starting out with relational data.

Figure 11-11 repeats the diagram you saw in the data management introduction chapter:

click to expand
Figure 11-11:

Figure 11-11 describes how there are three types of object that can be used to access XML and hold it in memory as a document: XmlDocument , XmlDataDocument , and XPathDocument . We discussed the reason for having these three different document objects in Chapter 8; the XmlDataDocument is designed to act as a bridge between relational and XML data.

XmlDataDocument and DataSet Synchronization

The only real external difference between an XmlDocument object and an XmlDataDocument object is that the latter has a few extra properties and methods . The most useful is the DataSet property. This returns a reference to an object that contains the data in the XML document, but which is exposed as a DataSet object. This is a useful read-only property.

Figure 11-12 conceptualizes the way it works:

click to expand
Figure 11-12:

The XML document can be accessed through various Reader objects, loaded into an XmlDataDocument object (as mentioned in Chapter 8), and can also be loaded into a DataSet .

However, after you load the XML into an XmlDataDocument object, you can reference a DataSet object that contains the same data; this is equivalent to reading the data into that DataSet . More to the point, as you change the data in either the DataSet or the XmlDataDocument , the changes are reflected in both. They are completely and automatically synchronized.

This means there is no longer a distinction between the relational or XML types of data “ they are just two views of the same data. This works in part because behind the scenes, the .NET Framework data management objects all use XML as their standard persistence format.

Once you've got the data in an XmlDataDocument , you can access it using any of the techniques available in the relational and XML armories. The next example page demonstrates a few.

The DataSet-XML Synchronization Example

The Synchronization of the XmlDataDocument and DataSet objects ( xml-to-dataset.aspx ) example page shown in Figure 11-13 demonstrates some of the features of the integration we've just discussed. It takes an XML document and the matching XSD schema and loads them into a new XmlDataDocument object. As shown, there are hyperlinks in the page so that you can examine the XML and schema files “ they are basically the same ones used in the first couple of examples in this chapter.

click to expand
Figure 11-13:
Note

You must run the page in a browser on the web server itself to be able to open the XML document and schema using the physical paths in the hyperlinks in the page.

After loading the data into the XmlDataDocument , the code carries out four different tasks with it. It first displays a list of last names of all the authors in our data. We do this first using the standard methods exposed by the XML DOM (as per the W3C recommendations), and then using an XPathNavigator object with a recursive search function.

Then a DataGrid control displays all the rows in the table within the DataSet . Of course, you can get this DataSet from the XmlDataDocument object's DataSet property, but notice how we are already freely mixing our relational and XML terminology.

Finally, if you scroll to the bottom of this page (as shown in Figure 11-14), you'll see a heap of XML. This has been extracted from the DataSet object, using the GetElementFromRow method. Using this method, you can pull out specific rows of data and return just those rows as XML. We've got a simple and efficient automated relational-based technique for manipulating data and creating the equivalent XML.

click to expand
Figure 11-14:
The Code for This Example Page

There is a lot of code in this page, as you can confirm if you view the source. However, it is commented and divided into the four tasks being performed, and so is easy enough to follow. In the code listings here, we'll confine ourselves to the features that are relevant to the four tasks, and omit much of the surrounding code ( code that creates links in the page, error messages, and so on). The first step is to create the XmlDataDocument and load the schema and XML from disk:

  'create a new XmlDataDocument object   Dim objXMLDataDoc As New XmlDataDocument()     'load the XML schema into the XmlDataDocument object   objXMLDataDoc.DataSet.ReadXmlSchema(strSchemaPath)     'load the XML file into the XmlDataDocument object   objXMLDataDoc.Load(strXMLPath)  
Using the XML DOM Methods of the Document

Now you can use the XmlDataDocument object. First, the code demonstrates that the object behaves like a normal W3C-standard XMLDocument object by using the GetElementsByTagname method to create an XmlNodeList containing all the <LastName> elements in the document: Then you can iterate through this NodeList (collection) displaying all the element values:

  Dim objNode As XmlNode   Dim strResults As String = ""     'create a NodeList collection of all matching child nodes   Dim colElements As XmlNodeList   colElements = objXMLDataDoc.GetElementsByTagName("LastName")     'iterate through the collection getting the values of the   'child #text nodes for each one   For Each objNode In colElements   strResults &= objNode.FirstChild().Value & " &nbsp; "   Next     'then display the result   outDOMResult.innerHTML = strResults  
Using an XPathNavigator Object

As discussed in Chapter 8, the .NET Framework introduces a new object that can be used to navigate within an XML document. An XPathNavigator can be created from an XML document object of any type, by calling the CreateNavigator method of that document object. In the following code, we use an XPathNavigator to fetch the values of all the <LastName> elements in the XmlDataDocument by moving to the root element of the document and then calling a recursive function, which searches each child of the current element in turn looking for matches and extracting the values:

  'create a new XPathNavigator object using the XmlDataDocument object   Dim objXPNav As XPathNavigator   objXPNav = objXMLDataDoc.CreateNavigator()     'move to the root element of the document   objXPNav.MoveToRoot()     'and display the result of the recursive 'search' function   outXPNavResult.innerHTML = SearchForElement(objXPNav, "LastName")  
Note

We haven't listed our recursive SearchForElement function again here, as it's identical to the technique used in Chapter 8.

Displaying the Content of the DataSet

The next part of the page output is easy to create. The following code shows how to reference the DataSet property of the XmlDataDocument object, and from that access the first member of the Tables collection. This gives us a reference to the default DataTable within the DataSet .

We can use this reference to create a DataView object, and then assign the DataView to an ASP.NET DataGrid control that was previously defined within the page. This gives us a picture of the data as a standard relational rowset “ just as though we'd filled our DataSet table using a Connection , Command , and DataAdapter .

  'create a DataView object for the Books table in the DataSet   Dim objDataView As New DataView(objXMLDataDoc.DataSet.Tables(0))     'assign the DataView object to the DataGrid control   dgrResult.DataSource = objDataView   dgrResult.DataBind() 'and bind (display) the data  
Extracting XML Elements from the DataSet

The final task in this page is to demonstrate how to query the DataSet to extract individual rows as XML. The GetElementFromRow method takes as its parameter an object that represents a row in a DataTable “ a DataRow object. It returns an XML representation of that row.

You can create a reference to the DataTable in the DataSet , and then iterate through the rows. For each one, the GetElementFromRow method of the XmlDataDocument object is called, which returns an XmlElement object. You get a string representation of the element from its OuterXml property and HTML-encode it before displaying it in the page:

  'create a DataTable object for the Books table in the DataSet   Dim objDataTable As DataTable = objXMLDataDoc.DataSet.Tables(0)   Dim objRow As DataRow   Dim objXMLElement As XmlElement     'iterate through all the rows in this table   For Each objRow In objDataTable.Rows   'get an XML element that represents this row   objXMLElement = objXMLDataDoc.GetElementFromRow(objRow)   'HTMLEncode it because it contains XML element tags   strResults &= Server.HtmlEncode(objXMLElement.OuterXML) & "<br />"   Next     outFromRowResult.innerHTML = strResults 'and display the result  
Getting a DataRow Object from an XML Element

Interestingly, there is a mirror of this method, named GetRowFromElement . You can iterate through the elements in an XML document using the DOM methods or an XPathNavigator to get an XmlNodeList of element objects, or individual XmlElement references.

For each one, the GetRowFromElement method of the XmlDataDocument object that holds the document will return a DataRow object. This can then be accessed to extract field information, or even used to update the original XML document. So now there is even a way to edit an XML document using relational techniques.

  objThisRow = objXmlDataDoc.GetRowFromElement(objElement)   objThisRow("MyFieldName") = "This is the new value"  



Professional ASP. NET 1.1
Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)
ISBN: 0470384611
EAN: 2147483647
Year: 2006
Pages: 243

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