XmlWriter


Don't think of an XML document as just a string of characters and angle brackets that form a larger document; instead, it is an InfoSet or a representation of data as an object. When writing XML to a stream or a file, you might think it's easiest to simply use string concatenation to build a large string that you then write to a stream or file. I strongly warn against taking this approach. A far better approach is to use the .NET Framework, which provides you with an XML writer through the XmlWriter class.

XmlWriter is an abstract class that allows you to specify an uncached, forward-only stream that writes an XML document. The style in which the XML document is created is controlled by the XmlWriterSettings class. The XmlWriterSettings class, which is new to .NET 2.0, enables you to configure the behavior of the XmlWriter object even before you instantiate it.

Writing XML Using XmlTextWriter

Before venturing into the XmlWriterSettings class, take a look at a simple example of using the XmlTextWriter to construct an XML document to be written to disk. XmlTextWriter is a class that implements XmlWriter and enables you to output XML to files or an open stream. An example of this is illustrated in Listing 15-12.

Listing 15-12: Using the XmlTextWriter class to construct XML to be written to disk

image from book
      using System;      using System.Collections.Generic;      using System.Text;      using System.Xml;      using System.Xml.Serialization;      using System.IO;      namespace XmlSerializationProject      {          class Program          {              static void Main(string[] args)              {                  try                  {                     XmlSerializer classSerialization =                         new XmlSerializer(typeof(StockOrder));                     StockOrder so = new StockOrder();                     so.Symbol = "MSFT";                     so.Quantity = 100;                     XmlTextWriter tw = new                        XmlTextWriter("C:/MyXml.xml", Encoding.UTF8);                     classSerialization.Serialize(tw, so);                     tw.Close();                     Console.Write("Written to disk");                     Console.ReadLine();                  }                  catch (System.Exception ex)                  {                     Console.Error.WriteLine(ex.ToString());                     Console.ReadLine();                  }              }          }      } 
image from book

The code in Listing 15-12 continues some of the previous examples illustrated using the StockOrder class. This example again uses the XmlSerializer class to serialize an object to XML using the Serialize method. However, this time instead of outputting the results to a console application, an instance of the XmlTextWriter class is used as the output destination.

The XmlTextWriter class is being instantiated as follows:

      XmlTextWriter tw = new XmlTextWriter("C:/MyXml.xml", Encoding.UTF8); 

In this case, the first parameter points to the file to be created and the second parameter specifies the encoding to use for the XML document. Other possible encodings include:

  • q ASCII

  • q BigEndianUnicode

  • q Default

  • q Unicode

  • q UTF32

  • q UTF7

  • q UTF8

In this example, UTF8 is used as the encoding, and the results are specified to be written to the file MyXml.xml located in the root directory. After the XmlTextWriter object is in place, the next step is to use the XmlSerializer object, which takes an instance of XmlWriter in one of its constructions.

      classSerialization.Serialize(tw, so); 

In this case, being passed to the Serialize method includes the instance of the XmlTextWriter object (tw) and an instance of the StockOrder object (so). After running the application, you get a message that the XML has been written to disk. Looking into the root directory, you find the MyXml.xml file with the results illustrated in Figure 15-8.

image from book
Figure 15-8

You can notice a few things from the output displayed in Figure 15-8. First, the encoding has indeed been specified as you want it-to UTF8. You can find this in the XML document's <?xml> declaration. The other item to pay attention to (because it isn't as apparent from looking at the figure) is that I have the MyXml.xml document open in Notepad with word-wrapping turned off. The XML document is written out in a single, long string. Although this is fine for computers and programs, it isn't always that helpful to any humans who might have to open and alter the XML contents from time to time.

Writing XML Using XmlWriter

Next, instead of using the XmlTextWriter object to write your serialized XML to disk, take a look at performing the same operation with the XmlWriter object. This enables you to use the XmlWriterSettings object later to play around with the XML output. The following table details the properties of the XmlWriterSettings class.

Open table as spreadsheet

Property

Initial Value

Description

CheckCharacters

True

This property, if set to True, performs a character check on the contents of the XmlWriter object. Legal characters can be found at http://www.w3.org/TR/REC-xml#charsets.

CloseOutput

False

Allows you to close the XmlWriter instance and if set to true, allows to also close the underlying stream.

ConformanceLevel

Conformance Level.Document

Allows the XML to be checked to make sure that it follows certain specified rules. Possible conformance-level settings include Document, Fragment and Auto.

Encoding

Encoding.UTF8

Defines the encoding of the XML generated.

Indent

False

Defines whether the XML generated should be indented. Setting this value to true properly indents child nodes from parent nodes.

IndentChars

Two spaces

Specifies the number of spaces by which child nodes are indented from parent nodes. This setting only works when the Indent property is set to true.

NewLineChars

\r\n

Assigns the characters that are used to define line breaks.

NewLineHandling

NewLine Handling. Replace

Deals with the normalization of line breaks in the output. Possible settings include Replace, Entitize, and None.

NewLineOnAttributes

False

Defines whether a node's attributes should be written to a new line in the construction. This occurs only if the property is set to true.

OmitXmlDeclaration

False

Defines whether an XML declaration should be generated in the output. This omission only occurs if this property is set to true.

OutputMethod

Xml

Defines the output to use. Possible settings include Xml, Html, Text, and AutoDetect.

Using the XmlWriterSettings object, you can alter how the XML is written to disk. Instead of just a straight line of XML, use this new object to change this and some other settings. This is illustrated in Listing 15-13.

Listing 15-13: Using the XmlWriterSettings object to alter the XML output

image from book
      using System;      using System.Collections.Generic;      using System.Text;      using System.Xml;      using System.Xml.Serialization;      using System.IO;      namespace XmlSerializationProject      {          class Program          {              static void Main(string[] args)              {                  try                  {                     XmlSerializer classSerialization =                         new XmlSerializer(typeof(StockOrder));                     StockOrder so = new StockOrder();                     so.Symbol = "MSFT";                     so.Quantity = 100;                     XmlWriterSettings settings = new XmlWriterSettings();                     settings.CheckCharacters = true;                     settings.Encoding = Encoding.Unicode;                     settings.Indent = true;                     XmlWriter xw = XmlWriter.Create("C:/MyXml.xml", settings);                     classSerialization.Serialize(xw, so);                     xw.Close();                     Console.Write("Written to disk");                     Console.ReadLine();                  }                  catch (System.Exception ex)                  {                     Console.Error.WriteLine(ex.ToString());                     Console.ReadLine();                  }              }          }      } 
image from book

In this bit of code, before the XmlSettings object is created, an instance of the XmlWriterSettings is created and certain properties are assigned values to change elements like the encoding and to break up the lines and indent the XML generated. After the XmlWriterSettings object is established, you assign this instance of the XmlWriterSettings object to the XmlWriter object. This is done through the XmlWriter object's Create method.

Looking at the new MyXml.xml file in the root directory, you see the following results after running this console application. (See Figure 15-9.)

image from book
Figure 15-9

In this instance of opening the XML document in Notepad, I still have the Word Wrap feature turned off, but (as you can) see the XML contains the proper line breaks and indents. This makes the XML more readable and manageable. Also, because the encoding was set in through the XmlWriterSettings object to Encoding.Unicode, the encoding specified in the XML document is now set to utf-16.

Writing XML Programmatically Using XmlWriter

You can also use the XmlWriter object to create XML programmatically. This is illustrated in Listing 15-14.

Listing 15-14: Building XML programmatically with the XmlWriter object

image from book
      using System;      using System.Collections.Generic;      using System.Text;      using System.Xml;      using System.IO;      namespace XmlProject      {          class Program          {              static void Main(string[] args)              {                  try                  {                     XmlWriterSettings settings = new XmlWriterSettings();                     settings.CheckCharacters = true;                      settings.Encoding = Encoding.Unicode;                     settings.Indent = true;                     XmlWriter xw = XmlWriter.Create("C:/MyXml.xml", settings);                     xw.WriteStartDocument();                     xw.WriteStartElement("StockOrder");                     xw.WriteStartElement("Symbol");                     xw.WriteValue("MSFT");                     xw.WriteEndElement(); // Symbol                     xw.WriteStartElement("Quantity");                     xw.WriteValue(100);                     xw.WriteEndElement(); // Quantity                     xw.WriteStartElement("OrderTime");                     xw.WriteValue(DateTime.Now.ToUniversalTime());                     xw.WriteEndElement(); // OrderTime                     xw.WriteEndElement(); // StockOrder                     xw.WriteEndDocument();                     xw.Close();                     Console.Write("Written to disk");                     Console.ReadLine();                  }                  catch (System.Exception ex)                  {                     Console.Error.WriteLine(ex.ToString());                     Console.ReadLine();                  }              }          }      } 
image from book

First, establish any settings via the XmlWriterSettings class. In this case, you use the same settings form as before-setting the encoding and providing line breaks and indentation as appropriate. From there, the XmlWriter is established through the Create method passing in the string of the file to write to and the instance of the XmlWriterSettings class.

From there, the XML Infoset is created using some of the many methods that are available to the XmlWriter class. The idea here is to open an element, add any required attributes, add any values, and then close the element. You need to perform this write in a procedural manner. Before any elements can be added, however, you must open the document itself. This is done through the WriteStartDocument method.

      xw.WriteStartDocument(); 

After the document has been started, or opened, the next step is to create the first element in the document. Of course, the first element created is the root element-StockOrder. This is done by using the WriteStartElement method.

      xw.WriteStartElement("StockOrder"); 

Whenever you start (or open) an element, you must also end (or close) the element. As you can see from the previous example, however, the StockOrder element is not closed until the end of the document. You have to shut the elements in the appropriate order to achieve a properly structured XML document. The root element's closing node doesn't appear till the very end of the document, and this is where you use the WriteEndElement method for the StockOrder element.

      xw.WriteEndElement(); 

After you start an element using the WriteStartElement method, your next step is to either start creating some attributes for that particular element, give the element a value, or close the element (if the element will be empty). An example of writing a value to an element is shown here:

      xw.WriteValue(DateTime.Now.ToUniversalTime()); 

After you have completed creating the document and closed all the elements contained in the document, the last step is to end the document using the WriteEndDocument method.

      xw.WriteEndDocument(); 

Finally, you can't write the document to disk (as is specified in the Create method of the XmlWriter instance) until you instantiate the Close method of the instance.

      xw.Close(); 

Running this console application produces an XML file, MyXml.xml (as specified programmatically in this example).




Professional XML
Professional XML (Programmer to Programmer)
ISBN: 0471777773
EAN: 2147483647
Year: 2004
Pages: 215

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