Adding nodes, removing nodes, adding attributes, and changing attributes
In a previous tutorial, I explained how to read and change nodes in XML files, this is part two of that tutorial!
If you have not yet had a chance to read my other tutorial, please read it before continuing (here)
For this tutorial, I am going to set up a form like below:

On that form is a listbox and two buttons.
I am going to use an xml file that is structured like this one:
xml
<?xml version="1.0"?>
<config>
<Item>This is item #1!</Item>
<Item>This is item #2!</Item>
<Item>This is item #3!</Item>
</config>
To read this xml document, and put it's contents in our listbox, I will use this code in Form1_load:
csharp
private void Form1_Load(object sender, EventArgs e)
{
//Clear all of the items out of the list box
listBox1.Items.Clear();
//the path to the xml file
string path = "Config.xml";
//Open the filestream
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//create the xmldocument
System.Xml.XmlDocument CXML = new System.Xml.XmlDocument();
//load the xml into the XmlDocument
CXML.Load(fs);
//Get the number of nodes in the xml document
for (int i = 0; i < CXML.DocumentElement.ChildNodes.Count; i++)
{
//Add the innertext of the xml document to the listbox
listBox1.Items.AddRange(new object[] { CXML.DocumentElement.ChildNodes[i].InnerText });
}
//Close the filestream
fs.Close();
}
Now that we have that part of our program set up, let's continue with the adding and removing of nodes!
Section 1: Adding nodes
To add nodes to an xml document, we need to:
- Open the file
- Load the xml into a System.xml.xmlDocument
- Create a new xml element (or node)
- Load the InnerText of the new element
- Insert the new element into the XmlDocument
- Save the XmlDocument
To do this, we will create an event for our 'Add' button, in that event, we will type in code like this:
csharp
//The path to our config file
string path = "Config.xml";
//create the reader filestream (fs)
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//Create the xml document
System.Xml.XmlDocument CXML = new System.Xml.XmlDocument();
//Load the xml document
CXML.Load(fs);
//Close the fs filestream
fs.Close();
// create the new element (node)
XmlElement newitem = CXML.CreateElement("Item");
// Put the value (inner Text) into the node
newitem.InnerText = "This is item #" + (CXML.DocumentElement.ChildNodes.Count + 1).ToString() + "!";
//Insert the new XML Element into the main xml document (CXML)
CXML.DocumentElement.InsertAfter(newitem, CXML.DocumentElement.LastChild);
//Save the XML file
FileStream WRITER = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
CXML.Save(WRITER);
//Close the writer filestream
WRITER.Close();
//Update the contents of the listbox
Form1_Load(new object(), new EventArgs());
In detail, here is how we do it:
In this code:
csharp
//create the reader filestream (fs)
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
We are creating the filestream that will read our xml document, the filestream has 4 arguments:
- The path of the document to open
- FileAccess type - how the file is opened - there are a few different argument for this one
- How to open it - this can be set to Open, Write, or OpenWrite
- How to share the file with other applications while open
In this part:
csharp
// create the new element (node)
XmlElement newitem = CXML.CreateElement("Item");
// Put the value (inner Text) into the node
newitem.InnerText = "This is item #" + (CXML.DocumentElement.ChildNodes.Count + 1).ToString() + "!";
we are creating the new node to be inserted into the xml document.
Next,
csharp
//Insert the new XML Element into the main xml document (CXML)
CXML.DocumentElement.InsertAfter(newitem, CXML.DocumentElement.LastChild);
simply inserts the new node into the xml document.
At the end, we of course save the xml document to the file, notice the two changes since the first filestream:
- The FileMode has been changed to FileMode.Truncate <- that will empty the xml file before saving
- The FileAccess has been changed to FileAccess.Write <-Enables writing to the file
Section 2: Removing nodes
Now that we know how to read and write xml file and add nodes, we will now discuss how to remove a node.
Removing a node is much like adding a node:
- Open the xml file
- Load the xml into a System.xml.xmlDocument
- Remove the node from the XmlDocument
- Save the XmlDocument to the xml file
Here's the code:
csharp
if (listBox1.SelectedIndex > -1)
{
//The Path to the xml file
string path = "config.xml";
//Create FileStream fs
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//Create new XmlDocument
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
//Load the contents of the filestream into the XmlDocument (xmldoc)
xmldoc.Load(fs);
//close the fs filestream
fs.Close();
//Remove the xml node
xmldoc.DocumentElement.RemoveChild(xmldoc.DocumentElement.ChildNodes[listBox1.SelectedIndex]);
// Create the filestream for saving
FileStream WRITER = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
// Save the xmldocument
xmldoc.Save(WRITER);
//Close the writer filestream
WRITER.Close();
//Update the contents of the listbox
Form1_Load(new object(), new EventArgs());
}
In this code, first we are making sure that the user has selected an item in the listbox. Next the program opens the file, loads the file into XmlDocument xmldoc, removes the node from the XmlDocument, and saves it to the xml file.
Again, you can see the differences in how I am opening my filestreams.
Section 3: Adding an xml attribute
To add an attribute is rather simple:
- Open the xml file
- Load the xml into a System.xml.xmlDocument
- Create the new Attribute
- Set the new Attribute's inner text
- insert the attribute into the xmldocument
- Save the XmlDocument to the xml file
In this code, it will add an attribute to the first xml node
csharp
//The Path to the xml file
string path = "config.xml";
//Create FileStream fs
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//Create new XmlDocument
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
//Load the contents of the filestream into the XmlDocument (xmldoc)
xmldoc.Load(fs);
//close the fs filestream
fs.Close();
//Create the new xml attribute
XmlAttribute xmlat1 = xmldoc.CreateAttribute("ID");
xmlat1.InnerText = "001";
//Insert the xml attribute
xmldoc.DocumentElement.ChildNodes[0].Attributes.Append(xmlat1);
// Create the filestream for saving
FileStream WRITER = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
// Save the xmldocument
xmldoc.Save(WRITER);
//Close the writer filestream
WRITER.Close();
Section 4: Changing the contents of an xml attribute
To change an attribute of an xml node, we need to:
- Open the xml file
- Load the xml into a System.xml.xmlDocument
- Set the new Attribute's inner text
- Save the XmlDocument to the xml file
Here's how:
csharp
//The Path to the xml file
string path = "config.xml";
//Create FileStream fs
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//Create new XmlDocument
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
//Load the contents of the filestream into the XmlDocument (xmldoc)
xmldoc.Load(fs);
//close the fs filestream
fs.Close();
//Change the contents of the attribute
xmldoc.DocumentElement.ChildNodes[0].Attributes[0].InnerText = "002";
// Create the filestream for saving
FileStream WRITER = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
// Save the xmldocument
xmldoc.Save(WRITER);
//Close the writer filestream
WRITER.Close();
Assuming that there is an attribute for the first xml node, this will change it to 002.
That is the end of this XML tutorial, I hope it was useful to you, and thanks for reading!
-AJ32