The differences between an element and an attribute are:
- An attribute is considered a characteristic of an element. This means that
an attribute belongs to an element
- An element can have one or more attributes. An
attribute cannot have an element
- An attribute must be created in the start-tag of an element
- An element cannot be defined as part of an attribute. That is, an
attribute is subject to an element and an attribute doesn't own the
attribute
Practical Learning: Introducing Attributes
|
|
- Create a new Console Application named CountriesStatistics1
- To save the file, on the Standard toolbar, click the Save All button
- Accept all defaults and click Save
- In the Solution Explorer, right-click CountriesStatistics1 ->
Add -> New Item...
- In the Templates list, click XML File
-
Set the Name to continents and click Add
- Change the file as follows:
<?xml version="1.0" encoding="utf-8" ?>
<World>
</World>
|
- To save the file, on the main menu, click File -> Save continents.xml As...
- Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (you should be in that folder already). In the
sub-folder of the same name, open the bin sub-folder followed by the Release
sub-folder. Click Save
An attribute must be created inside the start-tag of an
element. To manually create an attribute, type the left angle bracket of the
element, followed by the name of the element, an empty space, and the name of the
attribute. The name follows the same rules we defined for names
in XML.
An attribute should have a value that can be used to
distinguish it. To specify the name of an attribute, assign a value as a string
to its name. Imagine you have an ISBN element
as a child of a Video element as follows:
<Video>
<ISBN>0-7888-1623-3</ISBN>
</Video>
In this case, since ISBN is simply a child of the Video
element, you can change the ISBN element to become an attribute of the Video
element as follows:
<Video ISBN="0-7888-1623-3">
Now, ISBN is an attribute of the Video element.
Operations on an XML Attribute |
|
In the .NET Framework, an attribute is represented by the XmlAttribute
class. Like all nodes, this class is based on the XmlNode class. The name
of an attribute is represented by its (read-only) Name property. The
value of an attribute is represented by its Value property . Besides Value, you can also use XmlAttribute.InnerText
or XmlAttribute.InnerXml to access the text of an attribute.
Manually Creating an Attribute |
|
An element can have 0, one, or more attributes. The attributes of an element are stored
in the Attributes property of an XmlElement object. The XmlElement.Attributes property
is based on a class called XmlAttributeCollection.
The XmlAttributeCollection class is based on the XmlNamedNodeMap
class.
Before
performing an attribute-related operation on an element, to find out whether the
element has any attribute, you can check the value of the Boolean HasAttributes
property of its XmlElement
element. If this property produces a true value, then the element has at least
one attribute; otherwise, the element doesn't have any.
While a certain element may have an attribute,
a sibling element with the same name may not have an attribute or may have a
completely different type of attribute. Here is an XML file with attributes in some elements:
<?xml version="1.0" encoding="utf-8" ?>
<Videos>
<Video ISBN="0-7888-1623-3">
<Title Screenplay="Marty Kaplan">The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors>
</Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title WrittenBy="Charlie Peter">Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
Remember that you can include white spaces to make your code
easy to read. This means that you can type an attribute on the next line of its
element's name. In the Lesson 36, we saw that every element must be
closed. We saw that we could close an element with an end-tag as follows:
<Video><ISBN>0-7888-1623-3</ISBN></Video>
We also saw that we could close an element locally as
follows: <Video />. If you create an attribute in an empty element, you
can also close it by typing the indicative forward slash before the right angle
bracket and after an empty space. Here is an example:
<Video ISBN="0-7888-1623-3" />
Practical Learning: Creating Simple Attributes
|
|
- Change the file continents.xml file as follows:
<?xml version="1.0" encoding="utf-8" ?>
<World>
<Continent Name="Africa"></Continent>
<Continent Name="Europe"></Continent>
<Continent Name="Asia"></Continent>
<Continent Name="South America"></Continent>
</World>
|
- Save the file
Programmatically Creating an Attribute |
|
As mentioned already, an attribute primarily belongs to an
element. This means that, when creating an attribute, you must specify what
element it would belong to. To support the attributes of an element, the XmlElement
class is equipped with the SetAttribute() method which is overloaded in
two versions. The first version of this method uses the following syntax:
public virtual void SetAttribute(string name, string value);
The first argument is the name of the new attribute and the
second argument will be its text. Before adding an attribute, you should first
identify its parent element. Here is an example that adds an attribute to the
root element:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
public static class Exercise
{
private static void CreateAttribute()
{
string strFilename = "Videos.xml";
XmlDocument docXML = new XmlDocument();
if (File.Exists(strFilename))
{
// Open the XML file
docXML.Load(strFilename);
// Create an attribute and add it to the root element
docXML.DocumentElement.SetAttribute("FileDesc",
"Personal Video Collection");
docXML.Save("Videos.xml");
}
}
static int Main(string[] args)
{
CreateAttribute();
return 0;
}
}
}
From the above Videos.xml file, this code would result in:
<?xml version="1.0" encoding="utf-8"?>
<Videos FileDesc="Personal Video Collection">
<Video ISBN="0-7888-1623-3">
<Title Screenplay="Marty Kaplan">The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors>
</Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title WrittenBy="Charlie Peter">Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
To support attribute addition, the XmlDocument class
is equipped with the CreateAttribute() method, which is overloaded in
three versions. The first version of this method has the following syntax:
public XmlAttribute CreateAttribute(string name);
This method expects the name of the attribute as argument.
If it succeeds, this method produces an XmlAttribute object. To add the
new attribute to an element, you can call the XmlElement.SetAttributeNote()
method. This method is overloaded in two versions. One of the versions uses the following syntax:
public virtual XmlAttribute SetAttributeNode(XmlAttribute newAttr);
This method expects an XmlAttribute object.
Here is an example that looks for a particular video in a collection and adds an
ISBN attribute to it:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
public static class Exercise
{
private static void CreateAttribute()
{
string strFilename = "Videos.xml";
XmlDocument docXML = new XmlDocument();
if (File.Exists(strFilename))
{
// Open the XML file
docXML.Load(strFilename);
// Create a new attribute
XmlAttribute atrXML = docXML.CreateAttribute("ISBN");
atrXML.Value = "0-7907-3900-3";
// Get a list of elements whose names are Video
XmlNodeList nodVideos = docXML.GetElementsByTagName("Video");
// Since we will look for a specific video, get the list of all titles
XmlNodeList nodTitles = docXML.GetElementsByTagName("Title");
// Visit each title
for (int i = 0; i < nodTitles.Count; i++)
{
// Look for a video whose title is "Her Alibi"
if (nodTitles[i].InnerText.Equals("Her Alibi"))
{
// Once you find that video, add the new attribute to it
((XmlElement)(nodVideos[i])).SetAttributeNode(atrXML);
}
}
docXML.Save("Videos.xml");
}
}
static int Main(string[] args)
{
CreateAttribute();
return 0;
}
}
}
From the above Videos.xml file, this code would result in:
<?xml version="1.0" encoding="utf-8"?>
<Videos FileDesc="Personal Video Collection">
<Video ISBN="0-7888-1623-3">
<Title Screenplay="Marty Kaplan">The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors>
</Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video ISBN="0-7907-3900-3">
<Title WrittenBy="Charlie Peter">Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
Practical Learning: Creating an Attribute
|
|
- Create a new function as follows:
using System;
using System.IO;
using System.Xml;
namespace CountriesStatistics1
{
public static class Program
{
private static void CreateContinent()
{
string strFilename = "continents.xml";
XmlDocument xmlDocContinents = new XmlDocument();
FileStream fsStatistics = null;
if (File.Exists(strFilename))
{
string strContinent = null;
try
{
fsStatistics = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsStatistics);
}
finally
{
fsStatistics.Close();
}
// Request the name of a continent from the user
Console.Write("Enter the name of a continent: ");
strContinent = Console.ReadLine();
// Create an element that the new attribute will be added to
XmlElement xmlNewContinent =
xmlDocContinents.CreateElement("Continent");
// Create a Continent element and set its value to
// that of the new continent
xmlNewContinent.SetAttribute("Name", strContinent);
// Add the element and its attribute to the document
xmlDocContinents.DocumentElement.AppendChild(xmlNewContinent);
// Save the XML file
xmlDocContinents.Save("continents.xml");
}
}
static int Main(string[] args)
{
CreateContinent();
return 0;
}
}
}
|
- Execute the application and create a continent. Here is an example:
Enter the name of a continent: North America
Press any key to continue . . .
|
- Close the DOS window
<?xml version="1.0" encoding="utf-8"?>
<World>
<Continent Name="Africa">
</Continent>
<Continent Name="Europe">
</Continent>
<Continent Name="Asia">
</Continent>
<Continent Name="South America">
</Continent>
<Continent Name="North America" />
</World>
|
The Parent of an Attribute |
|
Once an attribute has been created, to identify the element
it belongs to, you can access its XmlAttribute.OwnerElement property.
This property produces an XmlElement value.
If an element has an attribute you don't want or that you
don't need anymore, you can delete that attribute. You have various options, two
are available through the XmlElement class.
The attributes of an XmlElement object are considered stored in an
indexed list with the most left attribute at index 0, the second from left
at index 1, and so on. Based on this, to remove an attribute by locating it
based on its index, you can call the XmlElement.RemoveAt() method. Its
syntax is:
public virtual XmlNode RemoveAttributeAt(int i);
When calling this method, if an attribute exists at position
i, it will be deleted and the method would return it. If there is no attribute
at that index, the method doesn't do anything and it returns 0.
Using the XmlElement.RemoveAt() method to delete an
attribute can be uncertain because you would not know whether there is an
attribute at the specified position. An alternative is to specify the name of
the attribute you want to delete. To support this, the XmlElement class
is equipped with the RemoveAttribute() method, which is overloaded with
two versions. One of the versions of this method uses the following
syntax:
public virtual void RemoveAttribute(string name);
This method expects as argument the name of the attribute to
remove.
Another technique you can use consists of defining an
XmlAttribute object and submitting to its XmlElement parent to delete. To do
this, you can call the RemoveAttributeNode() method of the XmlElement
object. Its
syntax is:
public virtual XmlAttribute RemoveAttributeNode(XmlAttribute oldAttr);
When calling this method, pass the attribute object as
argument. If the attribute exists, it would be removed and the method would
return the deleted attribute. If the attribute doesn't exist, nothing would
happen.
The Collection of Attributes of an Element |
|
So far, we have used only one attribute per element.
Fortunately, you can create as many attributes as you judge necessary in an
element. To do this, type the name of each attribute, assign it a double-quoted
string and separate the attribute from the next with an empty space. Here is an
example of an element with different attributes:
<Video ISBN="0-7888-1623-3" ScreenRatio="Standard" SoundtrackAvailable="True" />
As mentioned already and as you should always remember, attributes
belong to an element. To support them, the attributes of an element are stored
in the Attributes property of the XmlElement class. The XmlElement.Attributes
property is based on a class called XmlAttributeCollection.
The XmlAttributeCollection class is based on the XmlNamedNodeMap
class. This class lays a foundation to access attributes using their names or
index in the collection.
To know the number of attributes in an element, you can
use the XmlNamedNodeMap.Count property.
Practical Learning: Adding Attributes
|
|
- Create a new Console Application named CountriesStatistics2
- To save the project, on the Standard toolbar, click the Save All button
- Accept all defaults and click Save
- In the Solution Explorer, right-click CountriesStatistics2 ->
Add -> New Item...
- In the Templates list, make sure XML File is selected.
Set the Name to continents and click Add
- Change the file as follows:
<?xml version="1.0" encoding="utf-8" ?>
<World Area="510,072,000,000"
Population="6,379,157,361">
<Continent Name="Africa"
Area="30,065,000"
Population="807,419,000">
<Country CountryName="Burundi"
Area="27,830"
Population="6,231,221"
Capital="Bujumbura" Code="bi" />
</Continent>
<Continent Name="Europe"
Area="9,938,000"
Population="730,916,000">
<Country CountryName="Italy"
Area="301,230"
Population="58,057,477"
Capital="Rome" Code="it" />
</Continent>
</World>
|
- To save the file, on the main menu, click File -> Save continents.xml As...
- Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (you should be in that folder already). In the
sub-folder of the same name, open the bin sub-folder followed by the Release
sub-folder. Click Save
To access an attribute by its position in the collection,
you can use the XmlNamedNodeMap.Item() method.
The XmlAttributeCollection class is equipped with an ItemOf
indexed property. This property is overloaded in three versions. The first
version has the following syntax:
public virtual XmlAttribute this[int i] {get;}
This property allows you to access an attribute by
considering that the attributes are stored in an array. The first or most left
attribute has an index of 0; the second attribute from left (of course without
counting the name of the element) has an index of 1, and so on.
It can be difficult and sometimes unpredictable, in some
scenarios, to access an attribute by its index because you must
know exactly where each attribute is positioned. Consider the following version
of our Videos.xml XML file:
<?xml version="1.0" encoding="utf-8" ?>
<Videos FileDesc="Personal Video Collection">
<Video ISBN="0-7888-1623-3"
ScreenRatio="Standard"
SoundtrackAvailable="True">
<Title StoryBy="Marty Kaplan and Jonathan Reynold"
Screenplay="Marty Kaplan">The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors></Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video ISBN="0-7907-3900-3">
<Title Screenplay="Charlie Peter">Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
In the first video, the name of the screenplay writer is
stored at index 1. In the second video, the name of the screenplay writer is
stored at index 0. In this case, it may not be a good item to use the index to
locate an attribute. Fortunately, the second version of the overloaded XmlAttributeCollection.ItemOf[]
property has the following syntax:
public virtual XmlAttribute this[string name] {get;}
With this version, you can explicitly specify the name of
the attribute that you want.
Practical Learning: Accessing an Attribute
|
|
- To display the continents, change the code as follows:
using System;
using System.IO;
using System.Xml;
namespace CountriesStatistics2
{
public static class Program
{
private static void ShowContinents()
{
string strFilename = "continents.xml";
XmlDocument xmlWorldStats = new XmlDocument();
FileStream fsWorldStats = null;
if (File.Exists(strFilename))
{
string strContinent = null;
try
{
fsWorldStats = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlWorldStats.Load(fsWorldStats);
}
finally
{
fsWorldStats.Close();
}
// Get a list of elements whose names are Continent
XmlNodeList lstContinents =
xmlWorldStats.GetElementsByTagName("Continent");
// Show the statistics on the continents
Console.WriteLine(" =-= Continents =-=");
Console.WriteLine("Name\tArea\t\tPopulation");
foreach(XmlNode attr in lstContinents)
{
Console.WriteLine("{0}\t{1}\t{2}",
attr.Attributes["Name"].InnerText,
attr.Attributes["Area"].InnerText,
attr.Attributes["Population"].InnerText);
}
}
}
public static int Main(string[] args)
{
ShowContinents();
return 0;
}
}
}
|
- Execute the application to see the result:
=-= Continents =-=
Name Area Population
Africa 30,065,000 807,419,000
Europe 9,938,000 730,916,000
|
- Close the DOS window
Whether using its index or name, after accessing an
attribute, you can manipulate it as you see fit. For example, you can change
or delete it using the same techniques we saw to perform on an individual
attribute.
As mentioned already, the attributes are stored as a list.
Because you have complete access to this list and the positions of its
attributes, when creating or adding a new attribute, you can specify the
position the new attribute should have in the collection. To create an attribute
as the first in an element, you can call the XmlAttributeCollection.Prepend()
method. Its syntax is:
public virtual XmlAttribute Prepend(XmlAttribute node);
Another technique you can use consists of locating an
attribute first. Once you have one, to create a new attribute before it, you can
call the XmlAttributeCollection.InsertBefore() method. Its syntax is:
public virtual XmlAttribute InsertBefore(XmlAttribute newNode,
XmlAttribute refNode);
To add a new attribute after the current one, you can call
the XmlAttributeCollection.InsertAfter() method. Its syntax is:
public virtual XmlAttribute InsertAfter(XmlAttribute newNode,
XmlAttribute refNode);
To add an attribute at the end of the list of attributes of
an element, you can call the XmlAttributeCollection.Append() method. Its
syntax is:
public virtual XmlAttribute Append(XmlAttribute node);
Practical Learning: Creating Attributes
|
|
- To allow the user to create a new continent, change the program as
follows:
using System;
using System.IO;
using System.Xml;
namespace CountriesStatistics2
{
public static class Program
{
private static void ShowContinents()
{
string strFilename = "continents.xml";
XmlDocument xmlWorldStats = new XmlDocument();
FileStream fsWorldStats = null;
if (File.Exists(strFilename))
{
try
{
fsWorldStats = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlWorldStats.Load(fsWorldStats);
}
finally
{
fsWorldStats.Close();
}
// Get a list of elements whose names are Continent
XmlNodeList lstContinents =
xmlWorldStats.GetElementsByTagName("Continent");
// Show the statistics on the continents
Console.WriteLine("\n===================================");
Console.WriteLine(" =-= Continents =-=");
Console.WriteLine("===================================");
Console.WriteLine("Name\tArea\t\tPopulation");
Console.WriteLine("===================================");
foreach (XmlNode attr in lstContinents)
{
Console.WriteLine("{0}\t{1}\t{2}",
attr.Attributes["Name"].InnerText,
attr.Attributes["Area"].InnerText,
attr.Attributes["Population"].InnerText);
Console.WriteLine("-----------------------------------");
}
}
}
private static void CreateNewContinent()
{
string strContinent = null;
string strArea = null;
string strPopulation = null;
// Open the XML file
XmlDocument xmlDocContinents = new XmlDocument();
string strFilename = "continents.xml";
FileStream fsContinents = null;
if (File.Exists(strFilename))
{
try
{
fsContinents = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsContinents);
}
finally
{
fsContinents.Close();
}
}
// Create a Continent element that the new attribute will be added to
XmlElement xmlNewContinent =
xmlDocContinents.CreateElement("Continent");
// Present the current list of continents to the user
ShowContinents();
// Request the name of a continent from the user
Console.Write("Enter a new continent: ");
strContinent = Console.ReadLine();
// Create a Name attribute using the continent that the user entered
xmlNewContinent.SetAttribute("Name", strContinent);
// Request the continent's area from the user
Console.Write("Enter the area of the continent: ");
strArea = Console.ReadLine();
// Create the Area attribute
xmlNewContinent.SetAttribute("Area", strArea);
// Request the population of the continent from the user
Console.Write("Enter the population of the continent: ");
strPopulation = Console.ReadLine();
// Create the Population attribute
xmlNewContinent.SetAttribute("Population", strPopulation);
// Add the element and its attribute to the document
xmlDocContinents.DocumentElement.AppendChild(xmlNewContinent);
// Save the XML file
xmlDocContinents.Save(strFilename);
ShowContinents();
}
public static int Main(string[] args)
{
int choice = 0;
Console.WriteLine(" =-= Main Menu =-=");
Console.WriteLine("0 - Quit");
Console.WriteLine("1 - Display Continents");
Console.WriteLine("2 - Create New Continent");
Console.Write("Your Choice? ");
choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
ShowContinents();
break;
case 2:
CreateNewContinent();
break;
}
Console.WriteLine();
return 0;
}
}
}
|
- Execute the application to test it. Here is an example:
=-= Main Menu =-=
0 - Quit
1 - Display Continents
2 - Create New Continent
Your Choice? 2
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
Enter a new continent: North America
Enter the area of the continent: 24490000
Enter the population of the continent: 514600000
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
Press any key to continue . . .
|
- Close the DOS window
<?xml version="1.0" encoding="utf-8"?>
<World Area="510,072,000,000" Population="6,379,157,361">
<Continent Name="Africa"
Area="30,065,000"
Population="807,419,000">
<Country CountryName="Burundi"
Area="27,830"
Population="6,231,221"
Capital="Bujumbura"
Code="bi" />
</Continent>
<Continent Name="Europe"
Area="9,938,000"
Population="730,916,000">
<Country CountryName="Italy"
Area="301,230"
Population="58,057,477"
Capital="Rome"
Code="it" />
</Continent>
<Continent Name="North America"
Area="24490000"
Population="514600000" />
</World>
|
- To allow the user to create a new country, change the file as
follows:
using System;
using System.IO;
using System.Xml;
namespace CountriesStatistics2
{
public static class Program
{
private static void ShowContinents()
{
string strFilename = "continents.xml";
XmlDocument xmlWorldStats = new XmlDocument();
FileStream fsWorldStats = null;
if (File.Exists(strFilename))
{
try
{
fsWorldStats = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlWorldStats.Load(fsWorldStats);
}
finally
{
fsWorldStats.Close();
}
// Get a list of elements whose names are Continent
XmlNodeList lstContinents =
xmlWorldStats.GetElementsByTagName("Continent");
// Show the statistics on the continents
Console.WriteLine("\n===================================");
Console.WriteLine(" =-= Continents =-=");
Console.WriteLine("===================================");
Console.WriteLine("Name\tArea\t\tPopulation");
Console.WriteLine("===================================");
foreach (XmlNode attr in lstContinents)
{
Console.WriteLine("{0}\t{1}\t{2}",
attr.Attributes["Name"].InnerText,
attr.Attributes["Area"].InnerText,
attr.Attributes["Population"].InnerText);
Console.WriteLine("-----------------------------------");
}
}
}
private static void CreateNewContinent()
{
string strContinent = null;
string strArea = null;
string strPopulation = null;
// Open the XML file
XmlDocument xmlDocContinents = new XmlDocument();
string strFilename = "continents.xml";
FileStream fsContinents = null;
if (File.Exists(strFilename))
{
try
{
fsContinents = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsContinents);
}
finally
{
fsContinents.Close();
}
}
// Create a Continent element that the new attribute will be added to
XmlElement xmlNewContinent =
xmlDocContinents.CreateElement("Continent");
// Present the current list of continents to the user
ShowContinents();
// Request the name of a continent from the user
Console.Write("Enter a new continent: ");
strContinent = Console.ReadLine();
// Create a Name attribute using the continent that the user entered
xmlNewContinent.SetAttribute("Name", strContinent);
// Request the continent's area from the user
Console.Write("Enter the area of the continent: ");
strArea = Console.ReadLine();
// Create the Area attribute
xmlNewContinent.SetAttribute("Area", strArea);
// Request the population of the continent from the user
Console.Write("Enter the population of the continent: ");
strPopulation = Console.ReadLine();
// Create the Population attribute
xmlNewContinent.SetAttribute("Population", strPopulation);
// Add the element and its attribute to the document
xmlDocContinents.DocumentElement.AppendChild(xmlNewContinent);
// Save the XML file
xmlDocContinents.Save(strFilename);
ShowContinents();
}
private static void AddCountry()
{
string strContinent = null;
string strCountry = null;
string strArea = null;
string strPopulation = null;
string strCapital = null;
string strCode = null;
string strFilename = "continents.xml";
// Open the XML file
XmlDocument xmlDocContinents = new XmlDocument();
FileStream fsContinents = null;
if (File.Exists(strFilename))
{
try
{
fsContinents = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsContinents);
}
finally
{
fsContinents.Close();
}
}
// Display the list of continents to the user
Console.WriteLine("Here is a list of the created continents");
ShowContinents();
// Request a continent from the user
Console.Write("Enter the desired continent: ");
strContinent = Console.ReadLine();
// Get a list of elements whose names are Continent
XmlNodeList lstContinents =
xmlDocContinents.GetElementsByTagName("Continent");
// Visit each Continent element
for (int i = 0; i < lstContinents.Count; i++)
{
// Get a list of the attributes of the current element
XmlAttributeCollection curAttributes =
lstContinents[i].Attributes;
// Check each attribute, looking for
// the continent that the user entered
for (int j = 0; j < curAttributes.Count; j++)
{
// Check if the current continent
// is the same that the user selected
if (curAttributes["Name"].InnerText == strContinent)
{
// Once you find one, get its XmlElement reference
XmlElement elmNewCountry =
xmlDocContinents.CreateElement("Country");
// Request the name of a country from the user
Console.Write("Enter the name of the country: ");
strCountry = Console.ReadLine();
// Create the country specified by the user
elmNewCountry.SetAttribute("CountryName", strCountry);
// Request the area of the country from the user
Console.Write("Enter the area of the country: ");
strArea = Console.ReadLine();
// Create the Area specified by the user
elmNewCountry.SetAttribute("Area", strArea);
// Request the population of the country from the user
Console.Write("Enter the population of the country: ");
strPopulation = Console.ReadLine();
// Create the Population attribute
elmNewCountry.SetAttribute("Population", strPopulation);
// Request the Capital of the country from the user
Console.Write("Enter the capital of the country: ");
strCapital = Console.ReadLine();
// Create the Capital attribute
elmNewCountry.SetAttribute("Capital", strCapital);
// Request the Internet Code of the country from the user
Console.Write("Enter the Internet Code of the country: ");
strCode = Console.ReadLine();
// Create the Internet Code attribute
elmNewCountry.SetAttribute("Code", strCode);
// Add the element (and its attribute) as
// a child of the current Continent
lstContinents[i].AppendChild(elmNewCountry);
// Save the XML file
xmlDocContinents.Save("Countries.xml");
break;
}
}
}
}
public static int Main(string[] args)
{
int choice = 0;
do
{
Console.WriteLine(" =-= Main Menu =-=");
Console.WriteLine("1 - Display Continents");
Console.WriteLine("2 - Create New Continent");
Console.WriteLine("3 - Create New Country");
Console.WriteLine("0 - Quit");
Console.Write("Your Choice? ");
choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
ShowContinents();
break;
case 2:
CreateNewContinent();
break;
case 3:
AddCountry();
break;
default:
break;
}
} while ((choice == 1) ||
(choice == 2) ||
(choice == 3));
Console.WriteLine();
return 0;
}
}
}
|
- Execute the application to test it. Here is an example:
=-= Main Menu =-=
1 - Display Continents
2 - Create New Continent
3 - Create New Country
0 - Quit
Your Choice? 2
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
Enter a new continent: Asia
Enter the area of the continent: 43810582
Enter the population of the continent: 3902404193
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
Asia 43810582 3902404193
-----------------------------------
=-= Main Menu =-=
1 - Display Continents
2 - Create New Continent
3 - Create New Country
0 - Quit
Your Choice? 3
Here is a list of the created continents
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
Asia 43810582 3902404193
-----------------------------------
Enter the desired continent: Europe
Enter the name of the country: Italy
Enter the area of the country: 301230
Enter the population of the country: 58751711
Enter the capital of the country: Rome
Enter the Internet code of the country: it
=-= Main Menu =-=
1 - Display Continents
2 - Create New Continent
3 - Create New Country
0 - Quit
Your Choice? 0
Press any key to continue . . .
|
- Close the DOS window
<?xml version="1.0" encoding="utf-8"?>
<World Area="510,072,000,000" Population="6,379,157,361">
<Continent Name="Africa"
Area="30,065,000"
Population="807,419,000">
<Country CountryName="Burundi"
Area="27,830"
Population="6,231,221"
Capital="Bujumbura" Code="bi" />
</Continent>
<Continent Name="Europe"
Area="9,938,000"
Population="730,916,000">
<Country CountryName="Italy"
Area="301,230"
Population="58,057,477"
Capital="Rome"
Code="it" />
</Continent>
<Continent Name="North America"
Area="24490000"
Population="514600000" />
<Continent Name="Asia"
Area="43810582"
Population="3902404193" />
</World>
|
Using the list of attributes of an element, you can delete
one or all attributes of an element. Since the attributes are stored in a
collection, you can locate the undesired attribute by its index and then delete
it. To do this, you can call the XmlAttributeCollection.RemoveAt() method. Its syntax
is:
public virtual XmlAttribute RemoveAt(int i);
This method expects the index of the attribute that needs to
be removed. As mentioned for the XmlAttributeCollection.ItemOf
indexed property, to efficiently use this RemoveAt() method, you should
know the exact index of the attribute, otherwise, you may access and therefore
delete the wrong attribute. An alternative is to explicitly identify the
attribute you want to delete. To do this, you can call the XmlAttributeCollection.Remove() method. Its syntax
is:
public virtual XmlAttribute Remove(XmlAttribute node);
This method takes as attribute the XmlAttribute
identification of the attribute you want to remove.
To delete all attributes of an element, you can call the XmlAttributeCollection.RemoveAll() method. Its syntax
is:
public virtual void RemoveAll();
This method would simply remove all attributes that belong
to an XmlElement object.
|
|