5.7 Read and Write XML Without Loading an Entire Document into Memory


5.7 Read and Write XML Without Loading an Entire Document into Memory

Problem

You need to read XML from a stream, or write it to a stream. However, you want to process the information one node at a time, rather than loading it all into memory with an XmlDocument .

Solution

To write XML, create an XmlTextWriter that wraps a stream and use Write methods (such as WriteStartElement and WriteEndElement ). To read XML, create an XmlTextReader that wraps a stream and call Read to move from node to node.

Discussion

The XmlTextWriter and XmlTextReader classes read or write XML directly from a stream one node at a time. These classes don't provide the same features for navigating and manipulating your XML as XmlDocument , but they do provide higher performance and a smaller memory footprint, particularly if you need to deal with extremely large XML documents.

To write XML to any stream, you can use the streamlined XmlTextWriter . It provides Write methods that write one node at a time. These include

  • WriteStartDocument , which writes the document prologue, and WriteEndDocument , which closes any open elements at the end of the document.

  • WriteStartElement , which writes an opening tag for the element you specify. You can then add more elements nested inside this element, or you can call WriteEndElement to write the closing tag.

  • WriteElementString , which writes an entire element, with an opening tag, a closing tag, and text content.

  • WriteAttributeString , which writes an entire attribute for the nearest open element, with a name and value.

Using these methods usually requires less code than creating an XmlDocument by hand, as demonstrated in recipes 5.2 and 5.3.

To read the XML, you use the Read method of the XmlTextReader . This method advances the reader to the next node, and returns true . If no more nodes can be found, it returns false . You can retrieve information about the current node through XmlTextReader properties, including its Name , Value , and NodeType .

To find out if an element has attributes, you must explicitly test the HasAttributes property and then use the GetAttribute method to retrieve the attributes by name or index number. The XmlTextReader class can access only one node at a time, and it can't move backward or jump to an arbitrary node, which gives much less flexibility than the XmlDocument class.

The following console application writes and reads a simple XML document using the XmlTextWriter and XmlTextReader classes. This is the same XML document created in recipes 5.2 and 5.3 using the XmlDocument class.

 using System; using System.Xml; using System.IO; using System.Text; public class ReadWriteXml {     private static void Main() {         // Create the file and writer.         FileStream fs = new FileStream("products.xml", FileMode.Create);         XmlTextWriter w = new XmlTextWriter(fs, Encoding.UTF8);         // Start the document.         w.WriteStartDocument();         w.WriteStartElement("products");         // Write a product.         w.WriteStartElement("product");         w.WriteAttributeString("id", "1001");         w.WriteElementString("productName", "Gourmet Coffee");         w.WriteElementString("productPrice", "0.99");         w.WriteEndElement();         // Write another product.         w.WriteStartElement("product");         w.WriteAttributeString("id", "1002");         w.WriteElementString("productName", "Blue China Tea Pot");         w.WriteElementString("productPrice", "102.99");         w.WriteEndElement();         // End the document.         w.WriteEndElement();         w.WriteEndDocument();         w.Flush();         fs.Close();         Console.WriteLine("Document created. " +          "Press Enter to read the document.");         Console.ReadLine();         fs = new FileStream("products.xml", FileMode.Open);         XmlTextReader r = new XmlTextReader(fs);         // Read all nodes.         while (r.Read()) {              if (r.NodeType == XmlNodeType.Element) {                 Console.WriteLine();                 Console.WriteLine("<" + r.Name + ">");                 if (r.HasAttributes) {                     for (int i = 0; i < r.AttributeCount; i++) {                         Console.WriteLine("\tATTRIBUTE: " +                           r.GetAttribute(i));                     }                 }             }else if (r.NodeType == XmlNodeType.Text) {                 Console.WriteLine("\tVALUE: " + r.Value);             }         }         Console.ReadLine();     } } 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

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