Writing XML Using XmlTextWriter

Writing XML Using XmlTextWriter

If you’ve read about XML, you’re probably aware that the W3C XML 1 specification describes the serialized form of XML—the way that XML appears when rendered as text—complete with angle brackets, start tags and end tags, and namespace and XML declarations. If you’ve got some data that you want to write as XML, it isn’t hard to do it manually, but the .NET Framework provides you with the XmlTextWriter class to help with a lot of the formatting chores, such as keeping track of indentation and inserting namespace information everywhere it’s needed. The following tables list the properties and methods of the XmlTextWriter class.




Determines whether the XML is output with indentation. The default is Formatting::None.


Determines the indentation level. The default is 2.


Represents the indentation character. The default is a space.


Determines whether to support namespaces. The default is true.


Represents the character used to quote attribute values. The value must be a single or double quotation mark, and the default is double.


Gets the state of the writer (discussed in the following text).


Gets a string that represents the value of the xml:lang attribute. The value will be null if there’s no xml:lang attribute in the current scope.


Represents the value of the xml:space attribute.

The state of the writer tells you what the writer is doing at the point where you query the property. It will report one of the values from the WriteState enumeration, such as Start (no write methods have been called yet), Closed, Attribute (it’s writing an attribute), or Content (it’s writing element content).




Closes the writer and the underlying stream


Flushes whatever is in the buffer


Returns the current namespace prefix, if any


Writes out a set of attributes


Writes an attribute with a specified value


Encodes binary bytes as Base64 or BinHex, and writes the text


Writes text as a CDATA section


Writes a Unicode character as a hexadecimal character entity


Writes text one buffer at a time


Writes text as an XML comment


Writes a DOCTYPE declaration


Writes an entity reference


Writes a full end element tag


Writes a name, making sure it’s a valid XML name


Writes an XML processing instruction


Writes an XML qualified name


Writes raw markup manually


Writes the start and end of an attribute


Writes the start and end of a document


Writes the start and end of an element


Writes text


Writes white space

As you can see from the preceding table, to write elements, attributes, and documents, you need to call a start and an end function. When using XmlTextWriter, you don’t simply write an element; you write the start tag, then write its content, and then write the end tag. Therefore, you have to keep track of where you are in the document to ensure that you call the correct end functions at the correct time.

This exercise shows you how to write a simple XML document using XmlTextWriter and uses most of the major member functions of the class.

  1. Start a new Visual C++ Console Application (.NET) project named CppXmlWriter.

  2. Add the following two lines to the top of CppXmlWriter.cpp. These lines reference the XML DLL and help you access the namespace members.

    #using <System.xml.dll> using namespace System::Xml;
  3. You’re going to supply the name of the XML document to write when you run the program from the command line, so change the declaration of the _tmain function to include the command-line argument parameters, as follows:

    int _tmain(int argc, char* argv[])
  4. Add this code to the start of the _tmain function to check the number of arguments and save the path:

    // Check for required arguments if (argc < 2) { Console::WriteLine(S"Usage: CppXmlWriter path"); return -1; } String* path = new String(argv[1]);
  5. Create an XmlTextWriter by adding the following code, which is very similar to the code used to create an XmlTextReader.

    try { // Create the writer... // Use the default encoding XmlTextWriter* writer = new XmlTextWriter(path, 0); } catch (Exception* pe) { Console::WriteLine(pe->ToString()); }

    The writer is created by specifying the path for the new file and the character encoding that should be used. Passing a null pointer means that the writer will use the default UTF-8 encoding, which is a good default choice.


    If you want to use another encoding, such as UTF-7 or ASCII, you can specify a System::Text::Encoding object of the appropriate type.

  6. Let’s write the XML declaration to the file. Add the following lines to the end of the code inside the try block:

    // Set the formatting writer->Formatting = Formatting::Indented; // Write the standard document start writer->WriteStartDocument(); // Flush and close writer->Flush(); writer->Close();

    XmlTextWriter can produce output indented or without formatting. The default is no formatting, so you need to set the Formatting property if you want indentation. The defaults for the indentation character (a space) and the indentation level (two characters) are usually quite acceptable.

    WriteStartDocument produces a standard XML declaration. To make sure that all the text is output to the file, you should call Flush and Close before exiting.

  7. Write the root element to the document, as shown here:

    // Write the standard document start writer->WriteStartDocument(); // Start the root element writer->WriteStartElement(S"geology"); // Close the root element writer->WriteEndElement(); 

    The content of the root element will go between the calls to WriteStartElement and WriteEndElement. There isn’t any content in this case, but you still need both calls. Build and run the application at this stage, giving the name of the XML file.

    CppXmlWriter test1.xml

    You’ll see that the program writes an empty root element.

    <?xml version="1.0"?> <geology />
  8. To see how some of the other methods of XmlTextWriter are used, add one of the volcano entries to the root element, as shown here:

    // Start the root element writer->WriteStartElement(S"geology"); // Start the volcano element writer->WriteStartElement(S"volcano"); // Do the name attribute writer->WriteAttributeString(S"name", S"Mount St.Helens"); // Write the location element writer->WriteStartElement(S"location"); writer->WriteString(S"Washington State, USA"); writer->WriteEndElement(); // Write the height element writer->WriteStartElement(S"height"); writer->WriteAttributeString(S"value", "9677"); writer->WriteAttributeString(S"unit", "ft"); writer->WriteEndElement(); // Write the type element writer->WriteStartElement(S"type"); writer->WriteString(S"stratovolcano"); writer->WriteEndElement(); // Write the eruption elements writer->WriteStartElement(S"eruption"); writer->WriteString(S"1857"); writer->WriteEndElement(); writer->WriteStartElement(S"eruption"); writer->WriteString(S"1980"); writer->WriteEndElement(); // Write the magma element writer->WriteStartElement(S"magma"); writer->WriteString(S"basalt, andesite and dacite"); writer->WriteEndElement(); // Close the volcano element writer->WriteEndElement(); // Close the root element writer->WriteEndElement();

    I’ve left in the root element code so that you can see how everything nests. Adding extra elements isn’t hard, but it’s rather long-winded, and you have to be careful to nest all the calls correctly.

  9. Build and run the program, providing it with a suitable file name. The file should contain XML that looks very much like this:

    <?xml version="1.0"?> <geology> <volcano name="Mount St.Helens"> <location>Washington State, USA</location> <height value="9677" unit="ft" /> <type>stratovolcano</type> <eruption>1857</eruption> <eruption>1980</eruption> <magma>basalt, andesite and dacite</magma> </volcano> </geology>

    You can see how all the elements contain their attributes, how they are nested correctly, and how everything is properly indented.

Microsoft Visual C++  .NET(c) Step by Step
Microsoft Visual C++ .NET(c) Step by Step
ISBN: 735615675
Year: 2003
Pages: 208

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