Home

The Collection of Attributes of an Element

 

Introduction

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 Practical Learning: Adding Attributes

  1. Create a new Console Application named CountriesStatistics2
  2. To save the project, on the Standard toolbar, click the Save All button
  3. Accept all defaults and click Save
  4. In the Solution Explorer, right-click CountriesStatistics2 -> Add -> New Item...
  5. In the Templates list, make sure XML File is selected.
    Set the Name to continents and click Add
  6. 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>
  7. To save the file, on the main menu, click File -> Save continents.xml As...
  8. 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

Access to an Attribute

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 Practical Learning: Accessing an Attribute

  1. 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;
            }
        }
    }
  2. 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
  3. Close the DOS window
 

Attribute Addition

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 Practical Learning: Creating Attributes

  1. 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;
            }
        }
    }
  2. 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 . . .
  3. 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>
  4. 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;
            }
        }
    }
  5. 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 . . .
  6. 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>

 

Attribute Removal

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.

 


Previous Copyright © 2006 FunctionX, Inc. Next