Home

Operations on an XML Attribute

 

Introduction

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

  1. 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>
  2. 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 Practical Learning: Creating an Attribute

  1. 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;
            }
        }
    }
  2. Execute the application and create a continent. Here is an example:
     
    Enter the name of a continent: North America
    Press any key to continue . . .
  3. 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.

Attribute Removal

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.

 

Previous Copyright © 2006 FunctionX, Inc. Next