The .NET Framework developers invested a lot of effort in finding ways to make code more efficient. One performance enhancement in evaluating XPath expressions is the ability to precompile an expression for reuse. This exercise shows you how to use the Compile method of the XPathNavigator class to create a precompiled XPath expression, represented as an XPathExpression object.
Estimated Time : 15 minutes.
Create a new Visual Basic .NET project to use for the Exercises in this chapter.
Add a new XML file to the project. Name the new file Books1.xml. Modify the XML for Books1.xml as follows :
<?xml version="1.0" encoding="UTF-8" ?> <Books> <Book Pages="1046"> <Author>Delaney, Kalen</Author> <Title> Inside Microsoft SQL Server 2000</Title> <Publisher> Microsoft Press</Publisher> </Book> <Book Pages="1000"> <Author>Gunderloy. Michael</Author> <Title> ADO and ADO.NET Programming</Title> <Publisher>Sybex</Publisher> </Book> <Book Pages="484"> <Author>Cooper, James W.</Author> <Title> Visual Basic Design Patterns</Title> <Publisher> Addison Wesley</Publisher> </Book> </Books>
Add a new XML file to the project. Name the new file Books2.xml. Modify the XML for Books2.xml as follows:
<?xml version="1.0" encoding="UTF-8" ?> <Books> <Book Pages="792"> <Author> LaMacchia, Brian A.</Author> <Title> .NET Framework Security</Title> <Publisher >Addison Wesley</Publisher> </Book> <Book Pages="383"> <Author>Bischof Brian</Author> <Title>The .NET Languages: A Quick Translation Guide</Title> <Publisher>Apress</Publisher> </Book> <Book Pages="196"> <Author>Simpson, John E.</Author> <Title>XPath and XPointer</Title> <Publisher>O'Reilly</Publisher> </Book> </Books>
Add a new form to the project. Name the new form Exercise2-1.vb.
Add a Label control, a TextBox control named txtXPath , a Button control named btnEvaluate , and a ListBox control named lbNodes to the form:
Double-click the Button control to open the form's module. Add this line of code at the top of the module:
Imports System.Xml.XPath
Add code to handle the button's Click event:
Private Sub btnEvaluate_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnEvaluate.Click ' Load the Books1.xml file Dim xpd1 As XPathDocument = _ New XPathDocument("..\Books1.xml") ' Get the associated navigator Dim xpn1 As XPathNavigator = _ xpd1.CreateNavigator() ' Precompile an XPath expression Dim xpe As XPathExpression = _ xpn1.Compile(txtXPath.Text) ' Retrieve nodes to ' match the expression Dim xpni As XPathNodeIterator = _ xpn1.Select(xpe) ' And dump the results lbNodes.Items.Clear() lbNodes.Items.Add(_ "Results from Books1.xml:") While xpni.MoveNext lbNodes.Items.Add(" " & _ xpni.Current.NodeType.ToString _ & ": " & _ xpni.Current.Name & " = " & _ xpni.Current.Value) End While ' Now get the second document Dim xpd2 As XPathDocument = _ New XPathDocument("..\Books2.xml") ' Get the associated navigator Dim xpn2 As XPathNavigator = _ xpd2.CreateNavigator() ' Retrieve nodes to ' match the expression ' Reuse the precompiled expression xpni = xpn2.Select(xpe) ' And dump the results lbNodes.Items.Add(_ "Results from Books2.xml:") While xpni.MoveNext lbNodes.Items.Add(" " & _ xpni.Current.NodeType.ToString _ & ": " & _ xpni.Current.Name & " = " & _ xpni.Current.Value) End While End Sub
Set the form as the startup form for the project.
Run the project. Enter an XPath expression (such as /Books/Book[@Pages="1000"]/Author ) and click the button. The code will precompile the expression and then use the precompiled version to select nodes from each of the two XML files, as shown in Figure 2.18.
If you'd like to experiment with the DiffGram format, you don't have to create DiffGrams by hand. You can use the WriteXml method of the DataSet object to create a DiffGram containing all the changes made since the DataSet was initialized . This exercise will walk you through the process of creating a DiffGram.
Estimated Time : 15 minutes.
Add a new form to the project. Name the new form Exercise2-2.vb.
Add a DataGrid control named dgProducts and a Button control named btnWriteDiffGram to the form.
Expand the Server Explorer treeview to show a Data Connection to the Northwind sample database. Drag and drop the connection to the form.
Drag a SaveFileDialog component from the toolbox and drop it on the form. Set the FileName property of the component to diffgram.xml .
Double-click the Button control to open the form's module. Add this line of code at the top of the module:
Imports System.Data.SqlClient
Enter code to handle events:
Dim dsProducts As DataSet = New DataSet() Private Sub Exercise2_2_Load(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Create a command to retrieve data Dim cmd As SqlCommand = _ SqlConnection1.CreateCommand cmd.CommandType = CommandType.Text cmd.CommandText = _ "SELECT * FROM Products " & _ "WHERE CategoryID = 6" ' Retrieve the data to the DataSet Dim da As SqlDataAdapter = _ New SqlDataAdapter() da.SelectCommand = cmd da.Fill(dsProducts, "Products") ' Bind it to the user interface dgProducts.DataSource = dsProducts dgProducts.DataMember = "Products" End Sub Private Sub btnWriteDiffGram_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnWriteDiffGram.Click ' Prompt for a filename SaveFileDialog1.ShowDialog() ' Write out the DiffGram dsProducts.WriteXml(_ SaveFileDialog1.FileName, _ XmlWriteMode.DiffGram) End Sub
Set the form as the startup form for the project.
Run the project. The form will display records from the Northwind Products table. Make some changes to the data; you can add, edit, or delete records using the DataGrid. Click the button and select a name for the DiffGram. Click Save to create the DiffGram. Open the new DiffGram in a text editor and inspect it to see how your changes are represented.
By combining an XML-synchronized DataSet with an XPath expression, you can use XPath to select information from a relational database. This exercise shows you how you can use a DataSet, an XmlDataDocument, and an XPathNavigator together.
Estimated Time : 25 minutes.
Add a new form to the project. Name the new form Exercise2-3.vb.
Add two Label controls, two TextBox controls ( txtSQLStatement and txtXPath ), two Button controls ( btnCreateDataSet and btnSelectNodes ), and a ListBox control named lbNodes to the form.
Expand the Server Explorer treeview to show a Data Connection to the Northwind sample database. Drag and drop the connection to the form.
Double-click one of the Button controls to open the form's module. Add these lines of code at the top of the module:
Imports System.Data.SqlClient Imports System.Xml Imports System.Xml.XPath
Enter code to load a DataSet and an XmlDataDocument when you click the first button:
Dim ds As DataSet Dim xdd As XmlDataDocument Private Sub btnCreateDataSet_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnCreateDataSet.Click ' Create a command to retrieve data Dim cmd As SqlCommand = _ SqlConnection1.CreateCommand cmd.CommandType = CommandType.Text cmd.CommandText = txtSQLStatement.Text ' Retrieve the data to the DataSet Dim da As SqlDataAdapter = _ New SqlDataAdapter() da.SelectCommand = cmd ds = New DataSet() da.Fill(ds, "Table1") ' Retrieve the XML form of the Dataset xdd = New XmlDataDocument(ds) End Sub
Enter code to evaluate the XPath expression when you click the second button:
Private Sub btnSelectNodes_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnSelectNodes.Click ' Get the associated navigator Dim xpn As XPathNavigator = _ xdd.CreateNavigator() ' Retrieve nodes to match ' the expression Dim xpni As XPathNodeIterator = _ xpn.Select(txtXPath.Text) ' And dump the results lbNodes.Items.Clear() While xpni.MoveNext lbNodes.Items.Add(_ xpni.Current.NodeType.ToString _ & ": " & xpni.Current.Name & _ " = " & _ xpni.Current.Value) End While End Sub
Set the form as the startup form for the project.
Run the project. Enter a SQL Statement that retrieves rows and click the first button. Then enter an XPath expression and click the second button. You'll see the XPath query results as a set of XML nodes, as shown in Figure 2.19.
1: | How are XML elements and attributes represented in DOM? |
A1: | XML elements are represented as nodes within the DOM. XML attributes are represented as properties of their parent node. |
2: | When should you use an XmlTextReader by itself instead of with an XmlDocument? |
A2: | The XmlTextReader provides forward-only, read-only access to XML data. For random access or for read-write access you should use the XmlDocument class or one of its derived classes. |
3: | Explain three ways to synchronize an XmlDataDocument with a DataSet. |
A3: | You can synchronize an XmlDataDocument and a DataSet by creating a DataSet from an XmlDataDocument, by creating an XmlDataDocument from a DataSet, or by creating both a DataSet and an XmlDataDocument from a schema. |
4: | Why should you use an explicit path instead of a document-wide wildcard in an XPath expression? |
A4: | XPath expressions containing an explicit path, such as /Customers/Customer/Order/OrderID , are faster to evaluate than document-wide wildcard expressions such as //OrderID . |
5: | What is the difference between the XPath expressions /Customers/Customer/Order[1] and (/Customers/Customer/Order)[1] ? |
A5: | /Customers/Customer/Order[1] selects the first order for each customer, whereas (/Customers/Customer/Order)[1] selects the first order in the entire document. |
6: | How can you instantiate an XPathNavigator object? |
A6: | You can instantiate an XPathNavigator object by calling the CreateNavigator method of the XmlDocument, XmlDataDocument, or XPathDocument classes. |
7: | What options are there for validating an XML file with the XmlValidatingReader object? |
A7: | You can use an XmlValidatingReader to validate an XML file for conformance with an embedded schema, an XSD file, a DTD file, or an XDR file. |
8: | What are the three main variants of the FOR XML clause in T-SQL? |
A8: | The three main variants of FOR XML are FOR XML RAW , FOR XML AUTO , and FOR XML EXPLICIT . |
9: | How can you generate schema information with the FOR XML clause in T-SQL? |
A9: | To include schema information with a FOR XML query, specify the XMLDATA option. |
10: | What data operations can be represented in a DiffGram? |
A10: | DiffGrams can represent insertions, deletions, and modifications of the data in a DataSet or SQL Server database. |
1: | Your application contains an XML file, Orders.xml, with the following content: <?xml version="1.0" encoding="utf-8" ?> <Orders> <Order OrderID="1"> <OrderDate>1/1/2003</OrderDate> </Order> <Order OrderID="2"> <OrderDate>1/2/2003</OrderDate> </Order> <Order OrderID="3"> <OrderDate>1/3/2003</OrderDate> </Order> </Orders> Your application also contains a form with a Button control named btnProcess and a ListBox control named lbNodes . The event handler for the Button control has this code: Private Sub btnProcess_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnProcess.Click Dim xtr As XmlTextReader = _ New XmlTextReader("..\Orders.xml") Do While xtr.Read If (xtr.NodeType = _ XmlNodeType.Attribute) _ Or (xtr.NodeType = _ XmlNodeType.Element) _ Or (xtr.NodeType = _ XmlNodeType.Text) Then If xtr.HasValue Then lbnodes.Items.Add(_ xtr.Value) End If End If Loop xtr.Close() End Sub What will be the contents of the ListBox after you click the Button?
|
A1: | D. The DOM does not include nodes for XML attributesonly for XML elements and the text that they contain. XML element nodes do not have a value. The only text that will be printed out is the value of the text nodes within the <OrderDate> elements. |
2: | Your application contains the following XML file: <?xml version="1.0" encoding="utf-8" ?> <Orders> <Order OrderID="1"> <OrderDate>1/1/2003</OrderDate> </Order> <Order OrderID="2"> <OrderDate>1/2/2003</OrderDate> </Order> <Order OrderID="3"> <OrderDate>1/3/2003</OrderDate> </Order> </Orders> Your application uses the ReadXmlSchema method of the DataSet object to create a DataSet with an appropriate schema for this XML file. Which of the following mappings between XML entities and DataSet entities will this method create?
|
A2: | B. The ReadXmlSchema method makes the root element in the XML file the DataSet, and then maps nested elements in the XML file to related DataTable objects in the DataSet. At the leaf level of the DOM tree, both elements and attributes are mapped to DataColumns. |
3: | Your application includes an XML file that represents inventory in a warehouse. Each inventory item is identified by 50 different elements. You need to work with 4 of these elements on a DataGrid control. You plan to create a DataSet containing the appropriate data that can be bound to the DataGrid control. How should you proceed?
|
A3: | D. Looping through all the nodes in an XmlDocument is comparatively slow. If you start with the full XML document or by calling the ReadXml method of the DataSet, the DataSet will contain all 50 elements. Using a schema file allows you to limit the DataSet to holding only the desired data. |
4: | You use a SqlDataAdapter to fill a DataSet with the contents of the Customers table in your database. The CompanyName of the first customer is "Biggs Industries." You synchronize an XmlDataDocument object with the DataSet. In the DataSet, you change the CompanyName of the first customer to "Biggs Limited." After that, in the XmlDataDocument, you change the Value of the corresponding Node to "Biggs Co." When you call the Update method of the SqlDataAdapter, what is the effect?
|
A4: | C. The DataSet and the XmlDataDocument represent two different views of the same data structure. The last change made to either view is the change that is written back to the database. |
5: | Your application contains the following XML file: <?xml version="1.0" encoding="utf-8" ?> <Customers> <Customer> <CustomerName>A Company</CustomerName> <Orders> <Order OrderID="1"> <OrderDate>1/1/2003</OrderDate> </Order> <Order OrderID="2"> <OrderDate>1/2/2003</OrderDate> </Order> </Orders> </Customer> <Customer> <CustomerName>B Company</CustomerName> <Orders> <Order OrderID="3"> <OrderDate>1/2/2003</OrderDate> </Order> <Order OrderID="4"> <OrderDate>1/3/2003</OrderDate> </Order> </Orders> </Customer> <Customer> <CustomerName>C Company</CustomerName> <Orders> <Order OrderID="5"> <OrderDate>1/4/2003</OrderDate> </Order> <Order OrderID="6"> <OrderDate>1/5/2003</OrderDate> </Order> </Orders> </Customer> </Customers> Which XPath expression will return the first OrderID for each customer?
|
A5: | C. /Customers/Customer/Orders/Order/ @OrderID[1] selects the first OrderID for each order. (/Customers/Customer/Orders/Order)[1]/ @OrderID selects the OrderID for the first order in the entire file. (/Customers/Customer/Orders/ Order/@OrderID)[1] selects the first OrderID in the entire file. The remaining choice is the correct one. |
6: | Your application contains the following XML file: <?xml version="1.0" encoding="utf-8" ?> <Customers> <Customer> <CustomerName>A Company</CustomerName> <Orders> <Order OrderID="1"> <OrderDate>1/1/2003</OrderDate> </Order> <Order OrderID="2"> <OrderDate>1/2/2003</OrderDate> </Order> </Orders> </Customer> <Customer> <CustomerName>B Company</CustomerName> <Orders> <Order OrderID="3"> <OrderDate>1/2/2003</OrderDate> </Order> <Order OrderID="4"> <OrderDate>1/3/2003</OrderDate> </Order> </Orders> </Customer> <Customer> <CustomerName>C Company</CustomerName> <Orders> <Order OrderID="5"> <OrderDate>1/4/2003</OrderDate> </Order> <Order OrderID="6"> <OrderDate>1/5/2003</OrderDate> </Order> </Orders> </Customer> </Customers> Which XPath expression will return the CustomerName for all customers who placed an order on 1/3/2003?
|
A6: | A. The filtering expression needs to start with the ./ operator to indicate that it is filtering nodes under the current node at that point in the expression. |
7: | Your application allows the user to perform arbitrary XPath queries on an XML document. The user does not need to be able to alter the document. Which approach will give you the maximum performance for these requirements?
|
A7: | D. The XPathDocument class is optimized for read-only XPath queries. |
8: | You are designing an application that will allow the user to explore the structure of an XML file. You need to allow the user to move to the parent node, next node, or first child node from the current node. Which object should you use to implement this requirement?
|
A8: | A. The XPathNavigator object provides random access movement within the DOM. The XmlReader and XmlTextReader objects provide forward-only movement. The XPathExpression object is useful for retrieving a set of nodes, but not for navigating between nodes. |
9: | Your XML document has an inline schema. What is the minimum number of errors that this document will generate if you validate it with the XmlValidatingReader class?
|
A9: | B. An inline schema cannot contain validation information for the root node of the document, so XML documents with inline schemas will always have at least one validation error. |
10: | You are retrieving customer data from a SQL Server database into an XML document. You want the CustomerName and ContactName columns to be translated into XML elements. Which clause should you use in your SQL statement?
|
A10: | C. The raw and auto modes of the FOR XML statement always map columns to attributes. Only explicit mode can map a column to an element. |
11: | Your application contains the following code: Private Sub btnReadXML_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnReadXML.Click Dim cmd As SqlCommand = _ SqlConnection1.CreateCommand ' Create a command to retrieve XML cmd.CommandType = CommandType.Text cmd.CommandText = _ "SELECT Customers.CustomerID, " & _ "Customers.CompanyName," & _ "Orders.OrderID, Orders.OrderDate " & _ "FROM Customers INNER JOIN Orders " & _ "ON Customers.CustomerID = " & _ "Orders.CustomerID " & _ "WHERE Country = 'Brazil' AND " & _ "OrderDate BETWEEN '1997-03-15' " & _ "AND '1997-04-15' " & _ "FOR XML AUTO, ELEMENTS" SqlConnection1.Open() ' Read the XML into an XmlReader Dim xr As XmlReader = _ cmd.ExecuteXmlReader() Dim xd As XmlDocument = _ New XmlDocument() xd.Load(xr) End Sub When you run this code, you receive an error on the line of code that attempts to load the XmlDocument. What can you do to fix the problem?
|
A11: | C. The SqlCommand.ExecuteXmlReader method returns an XML fragment rather than an XML document. To load a complete and valid XML document, you need to use the SqlXmlCommand object (from the SQLXML Managed Classes) instead. |
12: | Your application contains the following code, which uses the SQLXML managed classes to apply a DiffGram to a SQL Server database: Private Sub btnUpdate_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnUpdate.Click ' Connect to the SQL Server database Dim sxc As SqlXmlCommand = _ New SqlXmlCommand(_ "Provider=SQLOLEDB;" & _ "Server=(local); " & _ "database=Northwind;" & _ "Integrated Security=SSPI") ' Set up the DiffGram sxc.CommandType = _ SqlXmlCommandType.DiffGram sxc.CommandStream = _ New FileStream("..\diffgram.xml", _ FileMode.Open) ' And execute it sxc.ExecuteNonQuery() MessageBox.Show(_ "Database was updated!") End Sub When you run the code, it does not update the database. The DiffGram is properly formatted. What should you do to correct this problem?
|
A12: | B. When executing a DiffGram via the SQLXML managed classes, you must supply a mapping schema file. Otherwise, the code doesn't know which elements in the DiffGram map to which columns in the database. |
13: | Which of these operations can be carried out in a SQL Server database by sending a properly-formatted DiffGram to the database? (Select two.)
|
A13: | A, C. DiffGrams are useful for performing data manipulation operations, but not for data definition operations. |
14: | You are developing code that uses the XPathNavigator object to navigate among the nodes in the DOM representation of an XML document. The current node of the XPathNavigator is an element in the XML document that does not have any attributes or any children. You call the MoveFirstChild method of the XPathNavigator object. What is the result?
|
A14: | A. The Move methods of the XPathNavigator object always execute without error. If the requested move cannot be performed, the current node remains unchanged, but the method returns False. |
15: | Which of these operations requires you to have an XML schema file?
|
A15: | A. You cannot perform a DiffGram update without a schema file that specifies the mapping between XML elements and database columns. Validation can be performed with a DTD or XDR file instead of a schema. XPath queries and reading XML files do not require a schema. |
1. Visual Studio .NET Combined Help Collection
Employing XML in the .NET Framework
XML and the DataSet
2. Microsoft SQL Server Books Online
Retrieving XML Documents Using FOR XML
SELECT statement
3. .NET Framework QuickStart Tutorials, Common Tasks QuickStart, XML section.
4. Gunderloy, Mike. ADO and ADO.NET Programming . Sybex, 2002.
5. Simpson, John E. XPath and XPointer . O'Reilly, 2002.
6. Griffin, John. XML and SQL Server . New Riders, 2001.
Top |