Writing New Values to an XML Document

In addition to reading existing documents, .NET makes creating an XML document from scratch very easy. The XML Creator program illustrates how this canbe done. Figures 10.14 and 10.15 show the XML Creator program in action. Whatmakes the XML Creator different from the XML Viewer is that the creator program can create XML without a pre-existing document. The XML Creator emphasizes how to create a new document and new nodes.

Figure 10.14. The XML displayed in the right panel was created by the program.


Figure 10.15. After entering a new element in the text boxes, pressing the Add button, and displaying the XML, a new element is visible in the code.


Designating the Class-Level Variables

No new classes are necessary to create an XML document. The program uses an XmlDocument named doc, an XmlNode named theNode, and a string to hold a file name:

private XmlDocument doc;
private XmlNode theNode;
private string fileName = "practice.xml";

Building the Document Structure

The XML document is created in the load method of the form. Creating the document is not difficult because it is simply a new instance of the XmlDocument class. However, creating the structure of the document takes some thought. For the XML Creator, I decided to build a simple address book. Figure 10.16 shows the basic document structure.

Figure 10.16. The document contains a contact, which is a group of person elements. Each person consists of a name, address, and phone number.


It’s a familiar refrain by now, but one that bears repeating. You need to sketch out a diagram like this before you start to code an XML document, or you’re going to get confused. Seeing the relationships between elements in your code can be difficult, but a diagram like this clarifies your intentions and makes the code much easier to write.

The code works by creating XmlElement variables for contact and person. theNode will be used as a temporary node. The first element in any document is the root (xml) node. A special method of the XmlDocument object is designed to simplify the creation of a root node: CreateXmlDeclaration() makes a root node. The parameters are almost always as listed. The first parameter stands for the XML type, which should always be "1.0". The second parameter stands for the encoding, which should always be "utf-8". The last parameter describes whether the document can stand alone. It should be "yes". After you create the root node, you still have to add it to the document. Use the AppendChild() method of the XmlNode class to add a child to a node (or to the document itself, which is also a node).

To create the other elements, use the CreateElement() method of the XmlDocument class. You will still need to use the AppendChild() method of whichever node you want to add the new child to. For example, the following code creates a node named contacts and appends it to the document object:

  //create contacts node
  contacts = doc.CreateElement("contacts");
  doc.AppendChild(contacts);

The next code fragment creates a person node and adds it as a child to contacts:

  //create first address
  person = doc.CreateElement("person");
  contacts.AppendChild(person);

When the basic structure is in place, it’s time to add some elements to the person class. Each of these elements is created just like contacts and person, but the other elements hold actual data. The easiest way to add information to a node is to set the InnerText property of the node in question. For example, here’s how I set up the name element:

  theNode = doc.CreateElement("name");
  theNode.InnerText = "Roger Dodger";
  person.AppendChild(theNode);

The entire code for the form’s load event shows how the entire document is designed:

private void XmlCreatorForm_Load(object sender,
    System.EventArgs e) {
  //initialize
  doc = new XmlDocument();

  XmlElement contacts;
  XmlElement person;

  //create root node
  theNode = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
  doc.AppendChild(theNode);

  //create contacts node
  contacts = doc.CreateElement("contacts");
  doc.AppendChild(contacts);

  //create first address
  person = doc.CreateElement("person");
  contacts.AppendChild(person);

  //create address elements
  theNode = doc.CreateElement("name");
  theNode.InnerText = "Roger Dodger"; 
  person.AppendChild(theNode); 
  theNode = doc.CreateElement("address");
  theNode.InnerText = "123 W 4th St.";
  person.AppendChild(theNode);

  theNode = doc.CreateElement("phone");
  theNode.InnerText = "123-4567";
  person.AppendChild(theNode);
} // end form load

As you can see from the code, it’s possible to create an XML document entirely from scratch, but you must have a solid idea of the document’s structure.

Adding an Element to the Document

You can create additional elements in the same way you create the first one. However, after the basic structure of an element is defined, it’s much easier to make a copy of an existing element than to build one from scratch. The code in btnAdd’s click event illustrates how this is done:

private void btnAdd_Click(object sender, System.EventArgs e) {
  //duplicate the person node
  XmlNode contacts;
  XmlNode person;
  XmlNode root;

  root = doc.FirstChild;
  contacts = root.NextSibling;
  person = contacts.FirstChild;
  theNode = person.Clone();

  //copy node values from text boxes
  theNode["name"].InnerText = txtName.Text;
  theNode["address"].InnerText = txtAddress.Text;
  theNode["phone"].InnerText = txtPhone.Text;

  //add the new node to contacts
  contacts.AppendChild(theNode); 

} // end btnAdd 

The first part of the code recreates the document’s structure by extracting the root node, the contacts node, and the person node. Next, I created a copy of the person node, named theNode, by using the Clone() method of the person node.

I then copied the values from the text boxes over to the new node. Notice how you can use the node’s name inside braces to specify which node you want to work with.

Finally, I added the new node to contacts.

Keep your diagram handy as you’re adding nodes. The document structure expects all person nodes to be added to the contacts node. You will get unpredictable results if you add the person node somewhere else.

Displaying the XML Code

To see that something is happening, I decided to display the code in the text box. In principle, this is very easy to do. Every node (including doc) has an OuterXml property that returns the XML code of the node and all its children (the InnerXml property returns the XML code of the node’s children, but not the node itself). However, the formatting that is useful for human readers (with carriage returns and indentation) is usually stripped out in the internal representations of XML code because it can confuse the parser (the part of the program that navigates the XML structure). Figure 10.17 illustrates what happens when you simply copy the internal XML to the text box.

Figure 10.17. The native XML code is complete but very difficult for humans to read.


Fortunately, the XmlDocument class has a property named PreserveWhiteSpace. When this property is set to true, the document is formatted for human reading. When the property is set to false, all whitespace (carriage returns and space characters) are removed. To get the effects of the PreserveWhiteSpace property, you need to reload the document.

The btnDisplay click event takes advantage of the PreserveWhiteSpace property to display the code in a human-readable format and then convert it back to the compressed form preferred by .NET:

private void btnDisplay_Click(object sender,
         System.EventArgs e) {
  //save the current document
  doc.Save(fileName);

  //display with whitespace
 doc.PreserveWhitespace = true;
 doc.Load(fileName);
 txtOutput.Text = doc.OuterXml;

 //reload without whitespace
 doc.PreserveWhitespace = false;
 doc.Load(fileName);

} // end btnDisplay

I started by saving the XML file as it currently exists to whatever file is determined by the fileName variable (set at the beginning of the program). I then set PreserveWhitespace to true, reloaded the document, and displayed the formatted version in the text box. The formatted version seemed to cause problems for some of the XML code, so I turned off PreserveWhitespace and reloaded the document again so that the version of doc in memory has no whitespace. There are other ways to automate the formatting of an XML document, but this appears to be the simplest.

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

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