Consider the following document saved in a file named Videos.xml: <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
</videos>
To let you add a new element and position it as the first in an XML document, the XmlNode class is equipped with a method named Prepend. Its syntax is: This method receives an argument as an XmlNode object and adds it on top of the XML document. Here is an example of calling it: using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;
public class Exercise : System.Windows.Forms.Form
{
Button btnAddFirst;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
btnAddFirst = new Button();
btnAddFirst.Text = "Add First";
btnAddFirst.Location = new Point(12, 12);
btnAddFirst.Click += new EventHandler(btnAddFirstClick);
Text = "Video Collection";
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnAddFirst);
}
void btnAddFirstClick(object sender, EventArgs e)
{
string Filename = "../../videos.xml";
XmlDocument xdVideos = new XmlDocument();
// Open the XML file
xdVideos.Load(Filename);
// Create a new XML element
XmlElement xeVideo = xdVideos.CreateElement("Video");
// Specify the child nodes of the element
xeVideo.InnerXml = "7243 4 92525 9 2" +
"<title>Yanni - Tribute</title>" +
"<director>George Veras</director>" +
"<format>DVD</format>";
// Add the new element as the first node in the document
xdVideos.DocumentElement.PrependChild(xeVideo);
// Save the file
xdVideos.Save(Filename);
}
}
public class Program
{
static int Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
System.Windows.Forms.Application.Run(new Exercise());
return 0;
}
}
This would produce: <?xml version="1.0" encoding="utf-8"?>
<videos>
<Video>7243 4 92525 9 2
<title>Yanni - Tribute</title>
<director>George Veras</director>
<format>DVD</format>
</Video>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
</videos>
Once again, consider our Videos.xml file: <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
<video>
<title>The Day After Tomorrow</title>
<director>Roland Emmerich</director>
<length>124 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
<video>
<title>Other People's Money</title>
<director>Alan Brunstein</director>
<length>114 Minutes</length>
<format>VHS</format>
<rating>PG-13</rating>
</video>
</videos>
Imagine you want to add a list of actors of the Her Alibi video. The first action to take is to locate the video, which you can do by calling the XmlDocument.GetElementsByTagName() method applied to a collection of nodes whose names are video. From this list of nodes, you can look for the node whose value is "Her Alibi". Once you have found this element, get a reference to its parent. Then add the new node as a child its parent. This can be done as follows: private void btnDocument_Click(object sender, EventArgs e)
{
string Filename = "videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(Filename))
{
xmlDoc.Load(Filename);
// Get a reference to the root node
XmlElement elmRoot = xmlDoc.DocumentElement;
// Create a list of nodes whose name is Title
XmlNodeList lstTitles = xmlDoc.GetElementsByTagName("title");
// Now you can check each node of the list
foreach (XmlNode node in lstTitles)
{
if (node.InnerText == "Her Alibi")
{
// Create an element named Actors
XmlElement elmNew = xmlDoc.CreateElement("actors");
XmlNode elmParent = node.ParentNode;
// Add a new element named Actors to it
elmParent.AppendChild(elmNew);
xmlDoc.Save(Filename);
}
}
}
}
This would produce: <?xml version="1.0" encoding="utf-8"?>
<videos>
. . .
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
<actors />
</video>
. . .
</videos>
This code creates an empty element. If you want to create an element that includes a value, create its text and add that text to the node. Here is an example: private void btnDocument_Click(object sender, EventArgs e)
{
string Filename = "videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(Filename))
{
xmlDoc.Load(Filename);
// Get a reference to the root node
XmlElement elmRoot = xmlDoc.DocumentElement;
// Create a list of nodes whose name is Title
XmlNodeList lstTitles = xmlDoc.GetElementsByTagName("title");
// Now you can check each node of the list
foreach (XmlNode node in lstTitles)
{
// When you get to a node, look for the element's value
// If you find an element whose value is Her Alibi
if (node.InnerText == "The Distinguished Gentleman")
{
// Create an element named Category
XmlElement elmNew = xmlDoc.CreateElement("category");
// Create the text of the new element
XmlText txtCatetory = xmlDoc.CreateTextNode("Comedy");
// Get a reference to the parent of the node we have found
XmlNode elmParent = node.ParentNode;
// Add the new element to the node we found
elmParent.AppendChild(elmNew);
// Specify the text of the new node
elmParent.LastChild.AppendChild(txtCatetory);
// Save the file
xmlDoc.Save(Filename);
}
}
}
}
This would produce: <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
<category>Comedy</category>
</video>
. . .
</videos>
Using the same approach combined with what we learned about adding an item, you can add a new element that itself has child nodes. Here is an example: private void btnDocument_Click(object sender, EventArgs e)
{
string Filename = "videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(Filename))
{
xmlDoc.Load(Filename);
// Get a reference to the root node
XmlElement elmRoot = xmlDoc.DocumentElement;
// Create a list of nodes whose name is Title
XmlNodeList lstTitles = xmlDoc.GetElementsByTagName("title");
// Now you can check each node of the list
foreach (XmlNode node in lstTitles)
{
// When you get to a node, look for the element's value
// If you find an element whose value is The Day After Tomorrow
if (node.InnerText == "The Day After Tomorrow")
{
// Create an element named Actors
XmlElement elmNew = xmlDoc.CreateElement("actors");
// Get a reference to the parent of the node we have found
XmlNode elmVideo = node.ParentNode;
// Add the new element to the node we found
elmVideo.AppendChild(elmNew);
// Create an element as a child of the new element
// Specify its name as Actor
elmNew = xmlDoc.CreateElement("actor");
// Create the text of the new element
XmlText txtActor = xmlDoc.CreateTextNode("Dennis Quaid");
// Add the new Actor element to the Actors node
elmVideo.LastChild.AppendChild(elmNew);
// Specify the text of the new node
elmVideo.LastChild.LastChild.AppendChild(txtActor);
// In the same way, add the other Actor nodes
elmNew = xmlDoc.CreateElement("actor");
txtActor = xmlDoc.CreateTextNode("Jake Gyllenhaal");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmNew = xmlDoc.CreateElement("actor");
txtActor = xmlDoc.CreateTextNode("Emmy Rossum");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmNew = xmlDoc.CreateElement("actor");
txtActor = xmlDoc.CreateTextNode("Dash Mihok");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
// Save the file
xmlDoc.Save(Filename);
}
}
}
}
This would produce: <?xml version="1.0" encoding="utf-8"?>
<videos>
. . .
<video>
<title>The Day After Tomorrow</title>
<director>Roland Emmerich</director>
<length>124 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
<actors>
<actor>Dennis Quaid</actor>
<actor>Jake Gyllenhaal</actor>
<actor>Emmy Rossum</actor>
<actor>Dash Mihok</actor>
</actors>
</video>
</videos>
You can also insert one or more elements as children of an existing node after locating that node. Here is an example: XML File <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
<category>Comedy</category>
</video>
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Mins</length>
<format>DVD</format>
<rating>PG-13</rating>
<actors />
</video>
</videos>
Code Fragment: private void btnDocument_Click(object sender, EventArgs e)
{
string Filename = "videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(Filename))
{
xmlDoc.Load(Filename);
// Get a reference to the root node
XmlElement elmRoot = xmlDoc.DocumentElement;
// Create a list of nodes whose name is Title
XmlNodeList lstTitles = xmlDoc.GetElementsByTagName("title");
// Now you can check each node of the list
foreach (XmlNode node in lstTitles)
{
// When you get to a node, look for the element's value
// If you find an element whose value is Her Alibi
if (node.InnerText == "Her Alibi")
{
// Get a reference to the video node that is
// the parent of the video titled Her Alibi
XmlNode elmVideo = node.ParentNode;
// Create a list of the child nodes of the Her alibi video
XmlNodeList lstActors = elmVideo.ChildNodes;
// Visit each item of the collection
// looking for an element named Actors
foreach (XmlNode nodActor in lstActors)
{
// If you find an element named Actors
if (nodActor.Name == "actors")
{
// Create a new element named Actor
// Specify its name as Actor
XmlElement elmNew = xmlDoc.CreateElement("actor");
// Create the text of the new element
XmlText txtActor = xmlDoc.CreateTextNode("Tom Selleck");
// Add the new Actor element to the Actors node
elmVideo.LastChild.AppendChild(elmNew);
// Specify the text of the new node
elmVideo.LastChild.LastChild.AppendChild(txtActor);
// Add other Actor nodes
elmNew = xmlDoc.CreateElement("actor");
txtActor = xmlDoc.CreateTextNode("Paulina Porizkova");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmNew = xmlDoc.CreateElement("actor");
txtActor = xmlDoc.CreateTextNode("William Daniels");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
// Save the file
xmlDoc.Save(Filename);
// Stop, in this example, we don't expect another Actors node
break;
}
}
}
}
}
}
This would produce: <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
<category>Comedy</category>
</video>
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
<actors>
<actor>Tom Selleck</actor>
<actor>Paulina Porizkova</actor>
<actor>William Daniels</actor>
</actors>
</video>
</videos>
Instead of simply adding a new node at the end of child nodes, you can specify any other position you want. For example, you may want the new node to precede an existing child node. To support this operation, the XmlNode class provides the InsertBefore() method. Its syntax is: public virtual XmlNode InsertBefore(XmlNode newChild, XmlNode refChild); The first argument of this method is the new node that will be added. The second argument is the sibling that will succeed the new node. Consider the following version of our Videos.xml file: <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
<category>Comedy</category>
</video>
<video>
<title>Fatal Attraction</title>
<director>Adrian Lyne</director>
<length>119 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
</videos>
Imagine you want to create a new category element below the director element whose name is Adrian Lyne. You can first get a list of videos. Inside of each video, check the nodes and find out whether the video has a director node whose text is Adrian Lyne. Once you find that node, you can add the new element after it. Here is an example: private void btnDocument_Click(object sender, EventArgs e)
{
string Filename = "videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(Filename))
{
xmlDoc.Load(Filename);
// Get a reference to the root node
XmlElement elmRoot = xmlDoc.DocumentElement;
// Create a list of the videos
XmlNodeList lstVideos = xmlDoc.GetElementsByTagName("video");
// visit each video
foreach (XmlNode node in lstVideos)
{
// Within a video, create a list of its children
XmlNodeList lstChildren = node.ChildNodes;
// Visit each child node
foreach (XmlNode dir in lstChildren)
{
// If the child node is (a director and its name is) Adrian Lyne
if (dir.InnerText == "Adrian Lyne")
{
// Create an element named Category
XmlElement elmNew = xmlDoc.CreateElement("category");
// Specify the text of the new element
elmNew.InnerText = "Drama";
// Insert the new node below the Adrian Lyne node Director
node.InsertAfter(elmNew, dir);
// Save the file
xmlDoc.Save(Filename);
// Stop
break;
}
}
}
}
}
This would produce: <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>
<format>DVD</format>
<rating>R</rating>
<category>Comedy</category>
</video>
<video>
<title>Fatal Attraction</title>
<director>Adrian Lyne</director>
<category>Drama</category>
<length>119 Minutes</length>
<format>DVD</format>
<rating>R</rating>
</video>
</videos>
In the same way, you can insert a new node after a child of a child (or of a child of a child of a child) of any node. If you want to new node to be positioned after an existing child node, you can call the XmlNode.InsertAfter() method. Its syntax is: public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild);
The .NET Framework implementation of XML provides various options to change the aspect, structure, or values, of an element. For example, you can use the same logic used in collection classes. This consists of locating a node and simply changing its value. Here is an example: <?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
<video>
<title>The Day After Tomorrow</title>
<director>Roland Emmerich</director>
<length>124 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
</videos>
----------------------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;
public class Exercise : System.Windows.Forms.Form
{
Button btnUpdate;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
btnUpdate = new Button();
btnUpdate.Text = "Update";
btnUpdate.Location = new Point(12, 12);
btnUpdate.Click += new EventHandler(btnUpdateClick);
Text = "Video Collection";
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnUpdate);
}
void btnUpdateClick(object sender, EventArgs e)
{
string Filename = "../../videos.xml";
XmlDocument xdVideos = new XmlDocument();
// Open the XML file
xdVideos.Load(Filename);
XmlNodeList xnlVideos = xdVideos.DocumentElement.GetElementsByTagName("title");
foreach (XmlNode xnVideo in xnlVideos)
{
if(xnVideo.InnerText.Contains("Day After Tomorrow") )
{
xnVideo.ParentNode.InnerXml = "<title>Day After Tomorrow(The)</title>" +
"<director>Roland Emmerich</director>" +
"<year>2004</year>" +
"<length>124 Minutes</length>" +
"<format>DVD</format>" +
"<rating>PG-13</rating>";
xdVideos.Save(Filename);
break;
}
}
}
}
public class Program
{
static int Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
System.Windows.Forms.Application.Run(new Exercise());
return 0;
}
}
----------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<title>Her Alibi</title>
<director>Bruce Beresford</director>
<length>94 Minutes</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
<video>
<title>Day After Tomorrow(The)</title>
<director>Roland Emmerich</director>
<year>2004</year>
<length>124</length>
<format>DVD</format>
<rating>PG-13</rating>
</video>
</videos>
On the other hand, the XmlNode class is equipped with a method named ReplaceChild. Its syntax is: To use this method, first locate an element and get its reference. Then change the values or child nodes you want, and finally replace the original value with the new version. In reality, and as its name implies, it is not the primary purpose of this method to edit or update an element. The role of this method is to use one node in place of another.
If you have a node you don't want or don't need anymore in the file, you can delete it. To delete a node, the XmlNode class provides the RemoveChild() method. Its syntax is: public virtual XmlNode RemoveChild(XmlNode oldChild); This method takes as argument the node to delete. If the node exists, it would be deleted and the method would return the node that was deleted. If the node does not exist, nothing would happen. To effectively use this method, you should first locate the particular node you want to delete. You can look for it using any of the logics we have applied so far. Once you find the node, you can then delete it. Imagine you want to delete a node whose name is Director and whose value is Bruce Beresford. Here is an example of calling this method to perform the operation: private void btnDocument_Click(object sender, EventArgs e)
{
string Filename = "videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(Filename))
{
xmlDoc.Load(Filename);
// Get a reference to the root node
XmlElement elmRoot = xmlDoc.DocumentElement;
// Create a list of the videos
XmlNodeList lstVideos = xmlDoc.GetElementsByTagName("video");
// visit each video
foreach (XmlNode node in lstVideos)
{
// Within a video, get a list of its children
XmlNodeList lstChildren = node.ChildNodes;
// Visit each child node
foreach (XmlNode dir in lstChildren)
{
// If the child node is Bruce Beresford
if (dir.InnerText == "Adrian Lyne")
{
node.RemoveChild(dir);
// Save the file
xmlDoc.Save(Filename);
// Stop
break;
}
}
}
}
}
To delete all child nodes of a node, you can call the XmlNode.RemoveAll() method. Its syntax is: public virtual void RemoveAll(); When called, this method will remove all child nodes, if any, of their parent node. Here is an example of calling it: using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;
public class Exercise : System.Windows.Forms.Form
{
Button btnDeleteEverything;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
btnDeleteEverything = new Button();
btnDeleteEverything.Width = 120;
btnDeleteEverything.Text = "Delete Everything";
btnDeleteEverything.Location = new Point(12, 12);
btnDeleteEverything.Click += new EventHandler(btnDeleteEverythingClick);
Text = "Video Collection";
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnDeleteEverything);
}
void btnDeleteEverythingClick(object sender, EventArgs e)
{
string Filename = "../../videos.xml";
XmlDocument xdVideos = new XmlDocument();
// Open the XML file
xdVideos.Load(Filename);
// Clear the XML document
xdVideos.DocumentElement.RemoveAll();
// Save the XML document
xdVideos.Save(Filename);
}
}
public class Program
{
static int Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
System.Windows.Forms.Application.Run(new Exercise());
return 0;
}
}
This would produce: <?xml version="1.0" encoding="utf-8"?> <videos> </videos> |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|