Chapter 21
Emitting XML with the XmlWriter

In This Chapter

Image Exploring the XmlWriter, Quickly

Image Using XmlTextWriter to Write an XML File

“Any sufficiently advanced technology is indistinguishable from magic.”

—Arthur C. Clarke

“Open the pod bay doors, Hal” Arthur C. Clarke is the author of, among other things, 2001: A Space Odyssey. I remember seeing it for the first time in 1980 or 1981. At that time, I had only trifled with a TRS-80 and GW-BASIC just a little bit (in 1978).

In 1978, I recall having fun tweaking the basic tank game, which is a little bit like Space Invaders turned sideways, but not nearly as fun to play as it was to tweak. (For very realistic Space Invaders fun (see Figure 21.1), check out http://spaceinvaders.de/. If you don’t know what Space Invaders is, then skip the sigh of nostalgia.)

Clarke basically meant new technology seems like magic. As technologists, it is our job to look behind the curtain. That said, this chapter was debatable for this book because it is not LINQ. This chapter actually demonstrates how the XmlWriter works. The XmlWriter was introduced in .NET 2.0. However, again as practicing magicians (as opposed to being part of the enthralled audience), it is helpful for you to know how the .NET Framework is gradually layering complexity within itself to make our jobs easier.

This short chapter demonstrates how to use the XmlWriter. It is worth clearly noting though that the XmlWriter is underneath XElement and XDocument in System.Xml.Linq—so if you are using LINQ to XML, you might not need to use the XmlWriter and its descendants directly, but the XmlWriter is the wizard behind the curtain.

Figure 21.1 Tragically, a lot of seventh-grade biology was skipped to play Space Invaders, but it is a trade I am happy to recall having made.

Image

Exploring the XmlWriter, Quickly

The XmlWriter class is an abstract class. Like an interface, this means you can declare it but you can’t instantiate it. More precisely, the left side of an assignment operator can be an XmlWriter, but the right side of the assignment operator must be one of its concrete descendants.

The basic behavior of the XmlWriter is that it has methods for writing the elements of a well-formed XML document, but this class doesn’t enforce a correct XML document.

The XmlWriter encodes binary data as base-64 data or hexadecimal values. You can specify whether namespaces are supported, flush and close documents, determine current namespaces, and write valid names and tokens. The XmlWriter doesn’t check for invalid elements or attributes, characters that don’t match the specified encoding, or duplicate characters. That is, using a derivative of the XmlWriter permits you to emit a poorly formed XML file.

Among some of the elements an XmlWriter will support are CDATA elements, comments, processing instructions, elements, and attributes. These behaviors are named accordingly. For example, to write out a <![CDATA[….]]> block, invoke the WriteCData method. (CDATA is text in an XML document that is not parsed by the XML parser.)

Using XmlTextWriter to Write an XML File

Chapter 20, “Constructing XML from Non-XML Data,” introduced functional construction with LINQ to XML. Functional construction is nested calls to classes like XElement. Underneath these constructional methods are several more lines of code containing calls to XmlTextWriter’s methods.

Listing 21.1 demonstrates how you can take commaseparated values like those returned from the Yahoo! quotes query and write them out long to an XML file using the XmlWriter. The code illustrates by counterexample how much extra leverage you get out of using LINQ to XML. (In Listing 21.1, there are many more lines of code to generate an XML file than there would be using LINQ to XML, as demonstrated in Listing 20.1 in Chapter 20.)

Listing 21.1 Producing an XML File Using the XmlWriter and an IO Stream

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Xml;

namespace WriteXmlFileWithXmlWriter
{
  class Program
  {
    static void Main(string[] args)
    {
     string all = GetQuotes(“MSFT GOOG DELL”);
     string[] quotes =
       all.Replace(“<b>”, ““).Replace(“</b>”, “”)
         .Replace(“””, ““).Split(new char[] { ‘ ’ },
         StringSplitOptions.RemoveEmptyEntries);

     using (XmlTextWriter writer =
      new XmlTextWriter(“quotes.xml”, System.Text.Encoding.UTF8))
     {

     writer.WriteStartDocument(true);
     writer.WriteStartElement(“Root”, ““);

     foreach (string str in quotes)
    {
    string[] fields =
       str.Split(new char[]{‘,’, ‘-’}, StringSplitOptions.RemoveEmptyEntries);
      writer.WriteStartElement(“Company”);
      writer.WriteValue(fields[0].Trim());
      writer.WriteStartElement(“LastPrice”);
      writer.WriteAttributeString(“Time”, fields[1].Trim());
      writer.WriteValue(fields[2].Trim());
      writer.WriteEndElement();
      writer.WriteElementString(“HighToday”, fields[3].Trim());
      writer.WriteEndElement();
    }

     writer.WriteEndElement();
     writer.WriteEndDocument();
     writer.Close();
    }
   }

   static string GetQuotes(string stocks)
  {
    string url =
      @“http://quote.yahoo.com/d/quotes.csv?s={0}&f=nlh”;

    HttpWebRequest request =
      (HttpWebRequest)HttpWebRequest.Create(string.Format(url, stocks));
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    using (StreamReader reader = new StreamReader(
     response.GetResponseStream(), Encoding.ASCII))
    {
      try
    {
       return reader.ReadToEnd();
    }
    finally
    {
     // don’t need to close the reader because Dispose does response.Close();
    }
   }
  }
 }
}

If you look back at Chapter 20, you will see that the LINQ query takes care of a lot of housekeeping, including the plumbing necessary to open and close XML tags.

This gradual layering of functionality, making things a little more seamless and requiring fewer lines of code, is the hallmark of a solid framework. In some technologies, new things happen in a big bang sort of way. The .NET Framework is layering solid features on existing, solid features gradually, permitting you to do more with fewer lines of code and less housekeeping. We might call this “good eats.”

Summary

The XmlWriter was introduced in the .NET Framework version 2.0. Built on top of that capability are the XElement and XDocument in the System.Xml.Linq namespace. XElement and XDocument layer in some additional plumbing that makes LINQ to XML (an additional layer) work. In a great framework like .NET Framework, you can achieve exceptional productivity by using the technologies like LINQ to XML or you can peel back layers, when necessary, and perform operations at a lower level of abstraction.

..................Content has been hidden....................

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