WEBSITE

ASP.NET 4 in VB 2010 : The XML Classes (part 4) - Reading an XML Document, Searching an XML Document

2/26/2013 6:30:19 PM

4. Reading an XML Document

The XDocument makes it easy to read and navigate XML content. You can use the shared XDocument.Load() method to read XML documents from a file, URI, or stream, and you can use the shared XDocument.Parse() method to load XML content from a string.

Once you have the XDocument with your content in memory, you can dig into the tree of nodes using a few key properties and methods of the XElement and XDocument class. Table 1 lists the most useful methods.

Table 1. Useful Methods for XElement and XDocument
MethodDescription
Attributes()Gets the collection of XAttribute objects for this element.
Attribute()Gets the XAttribute with the specific name.
Elements()Gets the collection of XElement objects that are contained by this element. (This is the top level only—these elements may in turn contain more elements.) Optionally, you can specify an element name, and only those elements will be retrieved.
Element()Gets the single XElement contained by this element that has a specific name (or null if there's no match). If there is more than one matching element, this method gets just the first one.
Descendants()Gets the collection of XElement objects that are contained by this element and (optionally) have the name you specify. Unlike the Elements() method, this method goes through all the layers of the document and finds elements at any level of the hierarchy.
Nodes()Gets all the XNode objects contained by this element. This includes elements and other content, such as comments. However, unlike the XmlTextReader class, the XDocument does not consider attributes to be nodes.
DescendantNodes()Gets all the XNode object contained by this element. This method is like Descendants() in that it drills down through all the layers of nested elements.

These methods give you added flexibility to filter out just the elements that interest you. For example, when using the Elements() method, you have two overloads to choose from. You can get all the child elements (in which case you would supply no parameters) or get just those child elements that have a specific element name (in which case you would specify the element name as a string). For example, here's how you would get the root <SuperProProductList> element from an XDocument that contains the complete SuperProProductList.xml:

' Use the Element() method, because there is just one matching element.
Dim superProProductListElement As XElement = doc.Element("SuperProProductList")

					  

You can then use this element as a starting point to dig deeper into the document. For example, if you want to find the child <Product> elements in the <SuperProProductList>, you would add this code:

' Use the Elements() method, because there are several matching elements.
Dim productElements = superProProductListElement.Elements("Product")

When defining the productElements object, this code does not specify a type. This shortcut works because the VB compiler can identify the correct type and fill it in automatically. (Technically, the Elements() method returns a strongly typed IEnumerable(Of XElement) collection, which is a generic collection that's customized to work with XElement objects.)

Getting the text inside an XElement is easy. In fact, Visual Studio is intelligent enough to automatically convert an XElement to the data type you want, as shown here:

Dim priceElement As XElement = productElement.Element("Price")
Dim price As Decimal = priceElement

This works because the XElement class defines specialized conversion operators. When you assign an XElement to a decimal variable, for example, the XElement automatically retrieves its inner value and attempts to convert that to a decimal.

If you have the Option Strict compilation set, which requires you to perform explicit data type conversion, you can use the same approach, but you need to use a conversion function like CType to make your intent clear to the VB compiler:

Dim priceElement As XElement = productElement.Element("Price")
Dim price As Decimal = CType(priceElement, Decimal)

Setting the text content inside an element is nearly as easy. You simply assign the new content to the Value property, as shown here:

priceElement.Value = CType(priceElement, Decimal) * 2;

You can use the same approach to read and set attributes with the XAttribute class.

Here's a straightforward code routine that mimics the XML processing code you saw earlier with the XmlTextReader. It scans through the elements that are available, creates a list of products, and displays that in a grid.

' Load the document.
Dim doc As XDocument = XDocument.Load(file)

' Loop through all the nodes, and create the list of Product objects .
Dim products As List(Of Product) = New List(Of Product)()

For Each element As XElement In _
  doc.Element("SuperProProductList").Elements("Product")
    Dim newProduct As New Product()
    newProduct.ID = element.Attribute("ID")
    newProduct.Name = element.Attribute("Name")
    newProduct.Price = element.Element("Price")

    products.Add(newProduct)
Next

' Display the results.
gridResults.DataSource = products
gridResults.DataBind()

' Display the retrieved document.
gridResults.DataSource = Products
gridResults.DataBind()

The XElement class offers quite a few more members. For example, you'll find members for quickly stepping from one node to the next (FirstNode, LastNode, NextNode, PreviousNode, and Parent), properties for testing for the presence of children (HasElements), attributes (HasAttributes), content (IsEmpty), and methods for inserting, removing, and otherwise manipulating the XML tree of nodes. For example, use Add() to place a new child element inside the current element (after any existing content); use AddFirst() to place a new child element inside the current element (before any existing content); use AddAfterSelf() to insert an element at the same level just after the current element; use AddBeforeSelf() to insert an element at the same level just before the current element; and so on. You can also use Remove(), RemoveNodes(), ReplaceWith(), and ReplaceNodes() to remove or replace elements and other nodes.

The following example shows how you can add a new product to the XDocument:

' Create the element for the new product.
Dim newProduct As New XElement("Product", _
  New XAttribute("ID", 4), _
  New XAttribute("Name", "Magic Lantern"), _
  New XElement("Price", "76.95"))

' Add the element to the end of the current product list.
doc.Element("SuperProProductList").Add(newProduct)

Whether you use the XDocument or the XmlTextReader class depends on a number of factors. Generally, you use XDocument when you want to deal directly with XML, rather than just using XML as a way to persist some information. It also gives you the ability to modify the structure of an XML document, and it allows you to browse XML information in a more flexible way (not just from start to finish). On the other hand, the XmlTextReader is best when dealing with large XML files, because it won't attempt to load the entire document into memory at once.


5. Searching an XML Document

One of the nicest features of the XDocument is its support of searching, which allows you to find nodes when you know they are there—somewhere—but you aren't sure how many matches exist or where the elements are.

To search an XDocument, all you need to do is use the Descendants() or DescendantNodes() method. Both methods allow you to search through the entire document tree in one step. For example, here's how you can use Descendants() on the entire SuperProProductList.xml document to get a list of prices:

Dim doc As XDocument = XDocument.Load(file)

' Find the matches.
Dim results = doc.Descendants("Price")
' Display the results. lblXml.Text = "<b>Found " & results.Count(Of XElement)().ToString() & " Matches " lblXml.Text &= " for the Price tag: </b><br /><br />" For Each result As XElement In results lblXml.Text += result.Value & "<br />" Next

Figure 6 shows the result.

Figure 6. Searching an XML document

The Descendants() method is great if you want to find an element based on its name. If you want to use more sophisticated searching, match only part of a name, or examine only part of a document, you have two choices. First, you can to write code that loops through all the nodes in the XDocument and checks each one. Second, you can use the LINQ to XML feature to perform a query that extracts matching XElement objects from your XDocument. This is a natural fit, because the XDocument class was originally introduced as part of the LINQ feature in .NET 3.5. 
Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone