XmlWriter
In This Chapter
Exploring the XmlWriter
, Quickly
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.
XmlWriter
, QuicklyThe 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.)
XmlTextWriter
to Write an XML FileChapter 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.)
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.”
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.
18.223.170.223