To programmatically create a new element, you can declare an
XmlElement variable. To add the new element to the file, the XmlDocument
class provides the CreateElement() method that is overloaded with three
versions. One of the versions uses the following syntax:
public XmlElement CreateElement(string name);
Using this method, to create a new element, call it and pass it the name of the new element. If you want the element to
have a value, the XmlDocument class is equipped with the CreateTextNode()
method. This method returns an XmlText value. The syntax of this method
is:
public virtual XmlText CreateTextNode(string text);
This method takes as argument the string that would
constitute the value of the element. The calls to XmlDocument.CreateElement()
and XmlDocument.CreateTextNode() allow you to initialize a new element.
In order to actually add the new element, you must specify its position in the
tree: whether it would be the first or the last node, whether you want to
position it before or after a node of your choice. To support the positions of
existing nodes, the XmlNode class, which is the ancestor of all XML nodes
of the .NET Framework, provides various appropriate methods.
One of these methods is AppendChild(), which is
used to add an element as the last child of its parent. The syntax of the XmlNode.AppendChild()
method is:
public virtual XmlNode AppendChild(XmlNode newChild);
Imagine you have a simple XML file that has only the root
and one level
of elements as follows:
<?xml version="1.0" encoding="utf-8"?>
<Holidays>
<Holiday>New Year's Day</Holiday>
<Holiday>Birthday of Martin Luther King, Jr.</Holiday>
<Holiday>Washington's Birthday</Holiday>
</Holidays>
To add a new Holiday element to this file, based on the
above discussions, you can use code as follows:
void AddHoliday()
{
XmlDocument docXML = new XmlDocument();
docXML.Load("Holidays.xml");
XmlElement elmXML = docXML.CreateElement("Holiday");
XmlText txtXML = docXML.CreateTextNode("Memorial Day");
docXML.DocumentElement.AppendChild(elmXML);
docXML.DocumentElement.LastChild.AppendChild(txtXML);
docXML.Save("Holidays.xml");
}
Practical Learning: Adding Elements
|
|
- To give the user the ability to create a new car make, change the
Exercise.cs file as follows:
// Project Name: CPAP1
// Application: College Park Auto-Parts
// Purpose: To Process XML Files
using System;
using System.Xml;
namespace CPAP1
{
static void CreateNewMake()
{
string strNewMake = 0;
Console.Write("Enter Car Make: ")
strNewMake = Console.ReadLine();
// Open the Makes.xml file
XmlDocument docXMLFile = new XmlDocument();
docXMLFile.Load("Makes.xml");
// Get the root node so we can explore its children
XmlElement nodRoot = docXMLFile.DocumentElement;
// Store all the values of the elements in a string
string allMyChildren = nodRoot.InnerText;
// Locate the new make among the values of the elements
int indexLookForNewMake = allMyChildren.IndexOf(strNewMake);
// If the car make exists already, don't add it
if( indexLookForNewMake >= 0 )
return;
else
{
// If the car is not in the list already, add it as a Make element
XmlElement elmXML = docXMLFile.CreateElement("Make");
// Create its value using the string provided by the user
XmlText txtXML = docXMLFile.CreateTextNode(strNewMake);
// Add the new element at the end of the file
docXMLFile.DocumentElement.AppendChild(elmXML);
// Specify its text
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
// Save the file
docXMLFile.Save("Makes.xml");
}
}
class Exercise
{
static int Main()
{
return 0;
}
}
}
|
- To give the user the ability to add a new car model, create the following
function in the file:
// Project Name: CPAP1
// Application: College Park Auto-Parts
// Purpose: To Process XML Files
using System;
using System.Xml;
namespace CPAP1
{
static void CreateNewMake()
{
string strNewMake = 0;
Console.Write("Enter Car Make: ")
strNewMake = Console.ReadLine();
// Open the Makes.xml file
XmlDocument docXMLFile = new XmlDocument();
docXMLFile.Load("Makes.xml");
// Get the root node so we can explore its children
XmlElement nodRoot = docXMLFile.DocumentElement;
// Store all the values of the elements in a string
string allMyChildren = nodRoot.InnerText;
// Locate the new make among the values of the elements
int indexLookForNewMake = allMyChildren.IndexOf(strNewMake);
// If the car make exists already, don't add it
if( indexLookForNewMake >= 0 )
return;
else
{
// If the car is not in the list already, add it as a Make element
XmlElement elmXML = docXMLFile.CreateElement("Make");
// Create its value using the string provided by the user
XmlText txtXML = docXMLFile.CreateTextNode(strNewMake);
// Add the new element at the end of the file
docXMLFile.DocumentElement.AppendChild(elmXML);
// Specify its text
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
// Save the file
docXMLFile.Save("Makes.xml");
}
}
static void CreateNewModel()
{
string strNewModel = 0;
Console.Write("Enter Car Model: ")
strNewModel = Console.ReadLine();
XmlDocument docXMLFile = new XmlDocument();
docXMLFile.Load("Models.xml");
XmlElement nodRoot = docXMLFile.DocumentElement;
string allMyChildren = nodRoot.InnerText;
int indexNewModel = allMyChildren.IndexOf(strNewModel);
if( indexNewModel >= 0 )
return;
else
{
XmlElement elmXML = docXMLFile.CreateElement("Model");
XmlText txtXML = docXMLFile.CreateTextNode(strNewModel);
docXMLFile.DocumentElement.AppendChild(elmXML);
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
docXMLFile.Save("Models.xml");
}
}
class Exercise
{
static int Main()
{
return 0;
}
}
}
|
- To guide the user with a menu, change the file as follows:
// Project Name: CPAP1
// Application: College Park Auto-Parts
// Purpose: To Process XML Files
using System;
using System.Xml;
namespace CPAP1
{
class Exercise
{
static void CreateNewMake()
{
string strNewMake = null;
Console.Write("Enter Car Make: ");
strNewMake = Console.ReadLine();
// Open the Makes.xml file
XmlDocument docXMLFile = new XmlDocument();
docXMLFile.Load("Makes.xml");
// Get the root node so we can explore its children
XmlElement nodRoot = docXMLFile.DocumentElement;
// Store all the values of the elements in a string
string allMyChildren = nodRoot.InnerText;
// Locate the new make among the values of the elements
int indexLookForNewMake = allMyChildren.IndexOf(strNewMake);
// If the car make exists already, don't add it
if( indexLookForNewMake >= 0 )
return;
else
{
// If the car is not in the list already, add it as a Make element
XmlElement elmXML = docXMLFile.CreateElement("Make");
// Create its value using the string provided by the user
XmlText txtXML = docXMLFile.CreateTextNode(strNewMake);
// Add the new element at the end of the file
docXMLFile.DocumentElement.AppendChild(elmXML);
// Specify its text
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
// Save the file
docXMLFile.Save("Makes.xml");
}
}
static void CreateNewModel()
{
string strNewModel = null;
Console.Write("Enter Car Model: ");
strNewModel = Console.ReadLine();
XmlDocument docXMLFile = new XmlDocument();
docXMLFile.Load("Models.xml");
XmlElement nodRoot = docXMLFile.DocumentElement;
string allMyChildren = nodRoot.InnerText;
int indexNewModel = allMyChildren.IndexOf(strNewModel);
if( indexNewModel >= 0 )
return;
else
{
XmlElement elmXML = docXMLFile.CreateElement("Model");
XmlText txtXML = docXMLFile.CreateTextNode(strNewModel);
docXMLFile.DocumentElement.AppendChild(elmXML);
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
docXMLFile.Save("Models.xml");
}
}
static int Main()
{
char mnuChoice = 'q';
Console.WriteLine();
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
Console.WriteLine("=-= College Park Auto-Parts =-=");
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
do {
Console.WriteLine("=-= Main Menu =-=");
Console.WriteLine("0 - Exit");
Console.WriteLine("1 - Add New Car Make");
Console.WriteLine("2 - Add New Car Model");
Console.Write("Your Choice: ");
mnuChoice = char.Parse(Console.ReadLine());
if( mnuChoice == '1' )
CreateNewMake();
else if( mnuChoice == '2' )
CreateNewModel();
if ( (mnuChoice != '0') && (mnuChoice != '1') && (mnuChoice != '2') )
Console.WriteLine("Invalid Choice: Please try again");
} while( mnuChoice != '0' );
Console.WriteLine("Thank you!");
return 0;
}
}
}
|
- Save the file
- Open the Command Prompt and Change to the Directory that contains
the above file, CPAP1
- To compile the exercise, type csc Exercise.cs and press Enter
- To execute the application, type Exercise and press Enter
- Using the menu, try adding a few car manufacturers (like Toyota and Honda)
and a few makes (like Neon, Civic, Camry, and Spider)
- Return to Notepad
Adding a Filled Child Element |
|
The above Holidays.xml file had only one level under the
root and no child element of the root had children. Suppose you have a file
as follows:
<?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 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
Imagine that you want to add a Video element. You have a
choice of adding one, more, or all child elements of the Video node. To perform
this operation, one solution you can use is to "build" all child
elements of the Video element, then add the node as a whole. To support this
technique, we saw earlier that the XmlNode.InnerXml property comprises a
node, its markup, its children and their markup. This means that you can create
the child nodes with their markup(s) as a string and assign that string to an XmlNode.InnerXml
string. To do this, you would need the set version of the InnerXml
property. It is declared as follows:
public virtual string InnerXml{get; set;}
Here is an example that adds a complete new Video node to
the above XML file:
static void DoIt()
{
XmlDocument docXML = new XmlDocument();
docXML.Load("Videos.xml");
XmlElement elmXML = docXML.CreateElement("Video");
string strNewVideo = "<Title>Other People's Money</Title>" +
"<Director>Alan Brunstein</Director>" +
"<Length>114 Minutes</Length>" +
"<Format>VHS</Format>" +
"<Rating>PG-13</Rating>";
elmXML.InnerXml = strNewVideo;
docXML.DocumentElement.AppendChild(elmXML);
docXML.Save("Videos.xml");
}
If you have an XML file with different levels and you want to
add an element as a new child to a particular element, you can first locate that
element. One way you can do this is to call the XmlDocument.GetElementByTagName()
method. This method is overloaded with two versions. One of its versions has
the following syntax:
public virtual XmlNodeList GetElementsByTagName(string name);
This method takes as argument the name of the element that
you want to locate. If the method finds that element, it returns a list of all
child nodes of that element as an XmlNodeList object. This XmlNodeList
object represents a collection of nodes where each node can be located by its
index through the ItemOf indexed property.
Practical Learning: Adding Elements
|
|
- To allow the user to create new parts, change the source code as follows:
// Project Name: CPAP1
// Application: College Park Auto-Parts
// Purpose: To Process XML Files
using System;
using System.Xml;
namespace CPAP1
{
class Exercise
{
static void CreateNewMake()
{
string strNewMake = null;
Console.Write("Enter Car Make: ");
strNewMake = Console.ReadLine();
// Open the Makes.xml file
XmlDocument docXMLFile = new XmlDocument();
docXMLFile.Load("Makes.xml");
// Get the root node so we can explore its children
XmlElement nodRoot = docXMLFile.DocumentElement;
// Store all the values of the elements in a string
string allMyChildren = nodRoot.InnerText;
// Locate the new make among the values of the elements
int indexLookForNewMake = allMyChildren.IndexOf(strNewMake);
// If the car make exists already, don't add it
if( indexLookForNewMake >= 0 )
return;
else
{
// If the car is not in the list already, add it as a Make element
XmlElement elmXML = docXMLFile.CreateElement("Make");
// Create its value using the string provided by the user
XmlText txtXML = docXMLFile.CreateTextNode(strNewMake);
// Add the new element at the end of the file
docXMLFile.DocumentElement.AppendChild(elmXML);
// Specify its text
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
// Save the file
docXMLFile.Save("Makes.xml");
}
}
static void CreateNewModel()
{
string strNewModel = null;
Console.Write("Enter Car Model: ");
strNewModel = Console.ReadLine();
XmlDocument docXMLFile = new XmlDocument();
docXMLFile.Load("Models.xml");
XmlElement nodRoot = docXMLFile.DocumentElement;
string allMyChildren = nodRoot.InnerText;
int indexNewModel = allMyChildren.IndexOf(strNewModel);
if( indexNewModel >= 0 )
return;
else
{
XmlElement elmXML = docXMLFile.CreateElement("Model");
XmlText txtXML = docXMLFile.CreateTextNode(strNewModel);
docXMLFile.DocumentElement.AppendChild(elmXML);
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
docXMLFile.Save("Models.xml");
}
}
static void AddNewPart()
{
int carYear;
string strMake, strModel, strPartNumber, strPartName;
double unitPrice;
//// - Generate a random number between 100000 and 999999 - ////
// We will generate a random number for the item
// To start, we will use the miliseconds as a seed
int ms = DateTime.Now.Millisecond;
Random rndNumber = new Random(ms);
int next = rndNumber.Next(100000, 999999);
// Display the new number in the Part # text box
strPartNumber = next.ToString();
//// - Let the user specify the car model year - ////
int curYear = DateTime.Now.Year + 1;
Console.WriteLine("Enter the following information as is related to the new car part");
Console.WriteLine("For the car model that the new part is made for, enter the year");
Console.Write("between 1960 and " + curYear + ": ");
carYear = int.Parse(Console.ReadLine());
//// - Display the list of Makes to the user to select one - ////
// We will need a reference to the XML document
XmlDocument docXML = new XmlDocument();
// Open the Makes.xml file
docXML.Load("Makes.xml");
// Get a reference to the root node
XmlElement nodRoot = docXML.DocumentElement;
// Locate all nodes whose name is Make
XmlNodeList nodItems = nodRoot.GetElementsByTagName("Make");
// Retrieve the value of each Make node and display
// that value to the user
Console.WriteLine("Here is a list of the car makes in our system");
for(int i = 0; i < nodItems.Count; i++)
Console.WriteLine(nodItems[i].InnerXml);
Console.Write("From this list, enter the car make of the new part: ");
strMake = Console.ReadLine();
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
//// - Display the list of car Models to the user to select one - ////
// Open the Models.xml file
docXML.Load("Models.xml");
// Get a reference to the root node
nodRoot = docXML.DocumentElement;
// Locate all nodes whose name is Model
nodItems = nodRoot.GetElementsByTagName("Model");
// Retrieve the value of each Model node and display
// that value to the user
Console.WriteLine("Here is a list of the car models in our system");
for(int i = 0; i < nodItems.Count; i++)
Console.WriteLine(nodItems[i].InnerXml);
Console.Write("From this list, enter the car model of the part: ");
strModel = Console.ReadLine();
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
//// - Request the part name - ////
Console.Write("Enter Part Name: ");
strPartName = Console.ReadLine();
//// - Request the unit price - ////
Console.Write("Enter Unit Price: ");
unitPrice = double.Parse(Console.ReadLine());
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("New Car Part Summary");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Part #: " + strPartNumber);
Console.WriteLine("Model Year: " + carYear);
Console.WriteLine("Car Make: " + strMake);
Console.WriteLine("Car Model: " + strModel);
Console.WriteLine("Part Name: " + strPartName);
Console.WriteLine("Unit Price: " + unitPrice);
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
// XmlDocument docXML = new XmlDocument();
docXML.Load("Parts.xml");
XmlElement elmXML = docXML.CreateElement("Part");
string strNewPart = "<PartNumber>" + strPartNumber + "</PartNumber>" +
"<CarYear>" + carYear.ToString() + "</CarYear>" +
"<Make>" + strMake + "</Make>" +
"<Model>" + strModel + "</Model>" +
"<PartName>" + strPartName + "</PartName>" +
"<UnitPrice>" + unitPrice.ToString() + "</UnitPrice>";
elmXML.InnerXml = strNewPart;
docXML.DocumentElement.AppendChild(elmXML);
docXML.Save("Parts.xml");
}
static int Main()
{
char mnuChoice = 'q';
Console.WriteLine();
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
Console.WriteLine("=-= College Park Auto-Parts =-=");
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
do {
Console.WriteLine("=-= Main Menu =-=");
Console.WriteLine("0 - Exit");
Console.WriteLine("1 - Add New Car Make");
Console.WriteLine("2 - Add New Car Model");
Console.WriteLine("3 - Add New Car Part");
Console.Write("Your Choice: ");
mnuChoice = char.Parse(Console.ReadLine());
if( mnuChoice == '1' )
CreateNewMake();
else if( mnuChoice == '2' )
CreateNewModel();
else if( mnuChoice == '3' )
AddNewPart();
if ( (mnuChoice != '0') && (mnuChoice != '1') &&
(mnuChoice != '2') && (mnuChoice != '3') )
Console.WriteLine("Invalid Choice: Please try again\n");
} while( mnuChoice != '0' );
Console.WriteLine("Thank you!");
return 0;
}
}
}
|
- Save the file and return to the Command Prompt
- To compile the exercise, type csc Exercise.cs and press Enter
- To execute the application, type Exercise and press Enter
- Using the menu, try adding a few car parts. Here are examples:
=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=
=-= College Park Auto-Parts =-=
=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=
=-= Main Menu =-=
0 - Exit
1 - Add New Car Make
2 - Add New Car Model
3 - Add New Car Part
Your Choice: 3
Enter the following information as is related to the new car part
For the car model that the new part is made for, enter the year
between 1960 and 2006: 1996
Here is a list of the car makes in our system
Acura
BMW
Dodge
Toyota
Honda
Hyundai
From this list, enter the car make of the new part: Dodge
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Here is a list of the car models in our system
NSX
TL
Spider
A4
RS6
323I
M5
Neon
Civic
Camry
From this list, enter the car model of the part: Neon
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Enter Part Name: Brake Pads
Enter Unit Price: 34.95
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
New Car Part Summary
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Part #: 973417
Model Year: 1996
Car Make: Dodge
Car Model: Neon
Part Name: Brake Pads
Unit Price: 34.95
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Main Menu =-=
0 - Exit
1 - Add New Car Make
2 - Add New Car Model
3 - Add New Car Part
Your Choice: 3
Enter the following information as is related to the new car part
For the car model that the new part is made for, enter the year
between 1960 and 2006: 1996
Here is a list of the car makes in our system
Acura
BMW
Dodge
Toyota
Honda
Hyundai
From this list, enter the car make of the new part: Honda
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Here is a list of the car models in our system
NSX
TL
Spider
A4
RS6
323I
M5
Neon
Civic
Camry
From this list, enter the car model of the part: Civic
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Enter Part Name: Passenger Mirror
Enter Unit Price: 24.65
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
New Car Part Summary
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Part #: 719266
Model Year: 1996
Car Make: Honda
Car Model: Civic
Part Name: Passenger Mirror
Unit Price: 24.65
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Main Menu =-=
0 - Exit
1 - Add New Car Make
2 - Add New Car Model
3 - Add New Car Part
Your Choice: 3
Enter the following information as is related to the new car part
For the car model that the new part is made for, enter the year
between 1960 and 2006: 1998
Here is a list of the car makes in our system
Acura
BMW
Dodge
Toyota
Honda
Hyundai
From this list, enter the car make of the new part: Honda
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Here is a list of the car models in our system
NSX
TL
Spider
A4
RS6
323I
M5
Neon
Civic
Camry
From this list, enter the car model of the part: Civic
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Enter Part Name: Brake Pads
Enter Unit Price: 34.85
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
New Car Part Summary
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Part #: 879207
Model Year: 1998
Car Make: Honda
Car Model: Civic
Part Name: Brake Pads
Unit Price: 34.85
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Main Menu =-=
0 - Exit
1 - Add New Car Make
2 - Add New Car Model
3 - Add New Car Part
Your Choice: 0
Thank you!
C:\CSharp Lessons\CPAP1>
|
- Type Exit and press Enter to close the DOS window
- Close Notepad to end the lesson
An XML tree navigation consists of visiting the various
nodes of the file, for any necessary reason. One reason would be that you want
to insert a new element at a specific position in the tree. Another would be
that you want to check whether a certain node is already present in the tree.
As always, there are various ways you can perform an
operation such as navigating a tree. To "scan" a file from top to
bottom, thus visiting each type of node in the XML file, you can use the XmlTextReader
class. This class is equipped with all types of properties and methods you would
need.
If you want to navigate to a specific node in the tree, you
can use the XmlDocument.GetElementByTagName() method that we used
previously.
|
|