Reading an XmlDocument

An XmlDocument can easily be loaded from disk using the Load( ) method. It has overloads for a Stream, filename, TextReader, or XmlReader, and the LoadXml( ) method will load an XML string from memory. This provides great flexibility; you can load an XmlDocument from a file, a web site, standard input, a memory buffer, or any subclass of Stream or TextReader, as well as any subclass of XmlReader.

For example, suppose the inventory file were stored on a web server, at http://www.angushardware.com/inventory.xml. The following code would let you read it:

XmlDocument document = new XmlDocument( );
document.Load("http://www.angushardware.com/inventory.xml");

After reading the entire document into memory, you now have non-sequential access to the entire XML tree. For example, you could easily navigate down to the number of each item in stock using the XmlNode type’s SelectNodes( ) method. SelectNodes( ) returns an XmlNodeList based on an XPath expression; in this case, you’re selecting all nodes that match the expression //items/item, and writing them to the console:

XmlDocument document = new XmlDocument( );
document.Load("http://www.angushardware.com/inventory.xml"); 
XmlNodeList items = document.SelectNodes("//items/item");
foreach (XmlElement item in items) {
  Console.WriteLine("{0} units of product code {1} in stock",
    item.GetAttribute("quantity"),
    item.GetAttribute("productCode"));
}

Tip

XPath is covered in Chapter 6.

Although you don’t necessarily know in what order the items will appear in the inventory file, you might want to print out the inventory in some reasonable order, such as by product code. While an XML Schema can alert you if elements in an XML document are in the wrong order, it can’t ensure that elements are ordered by an attribute value. To do this, you can create a private inner class called UnitInventory to hold a single product type’s inventory information. This class will implement the IComparable interface to permit easy sorting, and you can override ToString( ) to use the same object to print the inventory:

private class UnitInventory : IComparable {
  private string productCode;
  private int quantity;
  private string description;
  private double unitCost;

  public UnitInventory(string productCode, string quantity, 
    string description, string unitCost) {
    this.productCode = productCode;
    this.quantity = Int32.Parse(quantity);
    this.description = description;
    this.unitCost = Double.Parse(unitCost);
  }

  public int CompareTo(object other) {
    UnitInventory otherInventory = (UnitInventory)other;
    return productCode.CompareTo(otherInventory.productCode);
  }

  public override string ToString( ) {
    return quantity + " units of product code " +
      productCode + ", '" + description +
      "', in stock at $" + unitCost;
  }
}

Now you can create an instance of UnitInventory for each row returned by SelectNodes( ), add each to an ArrayList and sort the list, and, finally, write each item to the console:

XmlDocument document = new XmlDocument( );
document.Load("http://www.angushardware.com/inventory.xml"); 
XmlNodeList items = document.SelectNodes("//items/item");

ArrayList list = new ArrayList(items.Count);

foreach (XmlElement item in items) {
  list.Add(new UnitInventory(item.GetAttribute("productCode"),
    item.GetAttribute("quantity"),
    item.GetAttribute("description"),
    item.GetAttribute("unitCost")));
}
list.Sort( );

foreach (UnitInventory inventory in list) {
  Console.WriteLine(inventory);
}

If you run the program, you’ll see the list of inventory items sorted by the productCode attribute:

23 units of product code 1632S, '12 Piece Drill Bit Set', in stock at $14.95
15 units of product code R-273, '14.4 Volt Cordless Drill', in stock at $189.95
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.181.47