The Extensible Markup Language

Introduction to XML

The Extensible Markup Language, or XML, is a technique of using a document, such as a text file, to describe information and make that information available to whatever and whoever can take advantage of it. XML is neither a fancy technology nor a library. It is just a way to format the content of a document to make it easy for various applications or systems to read the document independent of who (the person, the company, etc) created it and how (by what means, what application, etc) it was created.

XML is just a text file. As we will see, this characteristic makes XML easy to create. Because XML is very flexible, it can be used in regular Windows applications, in databases, in web-based systems (Internet), in communication applications, in computer networks, in scientific applications, etc. To make sure that XML can be universally used without one person or group owning it, it is standardized by the W3C (http://www.w3c.org) organization. XML is released through an XML Recommendation document with a version.

To create an application that uses XML files, you have various options. You can start from a Console application, a Windows Forms Application, etc. In our series of lessons, we will use Windows Forms Applications. After starting the application, at one time, you must add or use an XML document.

To create an XML file, in the document, you type units of code using normal characters of the English language.

The XML document is made of units called entities. These entities are spread on various lines of the document as you judge them necessary and as we will learn. XML has strict rules as to how the contents of the document should or must be structured.

Practical LearningPractical Learning: Introducing XML Applications

  1. Start Microsoft Visual Studio 2022

    Create New Project

  2. In the Visual Studio 2022 dialog box, click Create a New Project
  3. In the Create a New Project wizard page, in the languages combo box, select C#

    Create New Project

  4. In the list of the projects templates, click Windows Forms App
  5. Click Next
  6. In the Configure Your New Project dialog box, change the project Name to IntroductionExtensibleMarkupLanguage
    Accept or change the project Location
  7. Click Next
  8. In the Framework combo box, select the highest version: .NET 8.0 (Long-Term Support)
  9. Click Create
  10. Double-click an unoccupied area of the form to generate its Load event
  11. To execute, on the main menu, click Debug -> Start Without Debugging
  12. Close the form and return to your programming environment
Author Note

Author Note

If you want, using the form of the application you created, you can apply the descriptions in the following sections to experiment with, and get, the same results.

A Parser for XML

After an XML document has been created and is available, in order to use it, you need a program that can read, analyze, and interpret it. This program is called a parser. The most popular parser used in Microsoft Windows applications is MSXML, published by Microsoft.

Markup

A markup is an instruction that defines XML. The fundamental formula of a markup is:

<tag>

The left angle bracket "<" and the right angle bracket ">" are required. Inside these symbols, you type a word or a group of words of your choice, using regular characters of the English alphabet and sometimes non-readable characters such as ?, !, or [. The combination of a left angle bracket "<", the right angle bracket ">", and what is inside of these symbols is called a markup. There are various types of markups we will learn.

The Document Type Declaration (DTD)

As mentioned above, XML is released as a version. Because there can be various versions, the first line that can be processed in an XML file must specify the version of XML you are using. The widely supported version of XML is 1.0. When creating an XML file, you should (should in 1.0 but must in 1.1) specify what version your file is following, especially if you are using a version higher than 1.0. For this reason, an XML file should (must) start, in the top section, with a line known as an XML declaration. Based on this, an XML document starts in the top line with <?xml version=, followed by the version you are using, assigned as a string, and followed by ?>. An example of such a line is:

<?xml version="1.0"?>

By default, an XML file created using Microsoft Visual Studio specifies the version as 1.0. Under the XML declaration line, you can then create the necessary tags of the XML file.

Encoding Declaration

As mentioned already, XML tags are created using characters of the alphabet and conform to the ISO standard. This is known as the encoding declaration. For example, most of the characters used in the US English language are known as ASCII. These characters use a combination of 7 bits to create a symbol (because the computer can only recognize 8 bits, the last bit is left for other uses). Such an encoding is specified as UTF-8. There are other standards such as UTF-16 (for wide, 2-Byte, characters).

To specify the encoding you are using, type encoding followed by the encoding scheme you are using, which must be assigned as a string. The encoding is specified in the first line. Here is an example:

<?xml version="1.0" encoding="utf-8"?>

Creating an XML File

There are various ways you can create and use an XML file. The most common technique consists of using a simple text editor. In Microsoft Windows, this would be Notepad. An XML file is first of all a normal text-based document that has a .xml extension. Therefore, however you create it, you must specify that extension.

Many other applications allow creating an XML file or generating one from an existing file. There are also commercial editors you can get or purchase to create an XML file.

Introduction to the Document Object Model

Writing XML Code

To support XML, the .NET Framework provides a namespace named System.Xml. When you create an XML file, there are standard rules you should (must) follow in order to have a valid document. The standards for an XML file are defined by the W3C Document Object Model (DOM). To support these standards, the System.Xml namespace provides a class named XmlDocument. This class allows you to create an XML document, to populate it with the desired contents, and to perform many other related operations on the contents of the file. Here is an example:

using System.Xml;

public class Exercise : System.Windows.Forms.Form
{
    public Exercise()
    {
        InitializeComponent();
    }

    void Exercise_Load(object sender, EventArgs e)
    {
        XmlDocument docMusicCollection = new XmlDocument();
    }
}

Writing XML Code Using XmlDocument

To create XML code using XmlDocument, the class is equipped with a method named LoadXml. Its syntax is:

public virtual void LoadXml(string xml);

This method takes a string as argument. The XmlDocument.LoadXml() method doesn't create an XML file, it only allows you to provide or create XML code. The code can be created as argument. You can also first declare and initialize a string variable with the XML code, then pass it as argument to the XmlDocument.LoadXml() method.

Writing XML Code Using the Code Editor

In the next sections, we will see how to create an XML file. After creating the file and displaying it in the Code Editor, you can start editing it. The Code Editor is equipped to assist you with various options. Whenever you start typing, the editor would display one or more options to you:

XML Code

When different options are presented to you, you can press the arrow keys to select an option and press Enter. You can also use the mouse to click an option. When typing other XML items, the Code Editor can assist you.

Saving an XML File

Introduction

Probably the most common way to create an XML file in Microsoft Windows consists of using Notepad or any other text editor. After opening the text editor, you can enter the necessary lines of code. After creating the file, you must save it. When saving it, you can include the name of the file in double-quotes. You can also first set the Save As Type combo box to All Files and then enter the name of the file with the .xml extension.

To assist you with creating XML Files, Microsoft Visual Studio includes an XML File option in the Add New Item dialog box. After selecting this option, you can accept the suggested name of the file or replace it in the Name text box. If you don't specify the extension, the wizard would add it for you.

Saving a DOM Object

If you call the XmlDocument.LoadXml() method, only the XML code is created, not the file. To let you save an XML file, the XmlDocument class is equipped with a method named Save. This method is provided in four versions. One of the versions takes as argument a string value. The syntax of this method is:

public virtual void Save(string filename);

The argument must be a valid filename or path. It must include the .xml extension. If you pass a string without backlashes, the file would be created in the same folder as the current project. If you want the file to be created somewhere else (in a different directory), pass the whole path.

If you want, especially for your practice, you can save your XML file(s) in one of the folders that are created by the computer (the operating system) when it is being set up. The most common of these folders is My Documents. To access one of those folders, you can use the Environment static class or the Environment.SpecialFolder enumeration.

Using File Information

As another way to start a file, you can use class named FileInfo:

public sealed class FileInfo : System.IO.FileSystemInfo

The FileInfo class is derived from FileSystemInfo. The FileInfo class has one constructor as follows:

public FileInfo (string fileName);

Therefore, you can declare a FileInfo variable and initialize it with this constructor. This can be done as follows:

using System.Xml;

namespace VideoCollection
{
    public partial class Exercise : Form
    {
        public Exercise()
        {
            InitializeComponent();
        }

        private void btnDocument_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new XmlDocument();
            
            string strVideos = @"E:\Videos Collection\Videos.xml";
            
            FileInfo fiVideos = new FileInfo(strVideos);
        }
    }
}

After declaring the variable, you can access its members such as the Name, the FullName, the Extension, or the Directory properties.

Checking the Existense of a File

Before doing anything on a file, you may want to first find out whether it exists already. To assist you with this, the File class is equipped with a method named Exists method. You can pass the name or path of the file. Here is an example:

using System.Xml;

namespace VideoCollection
{
    public partial class Exercise : Form
    {
        public Exercise()
        {
            InitializeComponent();
        }

        private void btnDocument_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new();
            string strVideos = @"C:\Videos Collection\Videos.xml";

            if(File.Exists(strVideos) == true)
            {
                // . . .
            }
        }
    }
}

As an alternative, you can access the FileInfo.Exist property. Here is an example:

using System.Xml;

namespace VideoCollection
{
    public partial class Exercise : Form
    {
        public Exercise()
        {
            InitializeComponent();
        }

        private void btnDocument_Click(object sender, EventArgs e)
        {
            var xdVideos = new XmlDocument();
            string strVideos = @"E:\Videos Collection\Videos2.xml";
            FileInfo fiVideos = new(strVideos);

            if (fiVideos.Exists == true)
            {
                // . . .
            }
        }
    }
}

Starting a Stream

As you may know already, when you are dealing with files, you save them to a medium, also called a stream. To support file processing or streaming, the .NET Framework provides the System.IO namespace.

To support streams, the System.IO namespace provides an abstract class named Stream:

public abstract class Stream : MarshalByRefObject, IAsyncDisposable, IDisposable

As you can see, Stream is an abstract class. Therefore, to use it, you need a class derived from it. An example of such a class is FileStream. You can declare a variable of that class, initialize it with a file name before using it. You can do this in a Operator. This can be done as follows:

Opening an XML File

Introduction

Whether you created an XML file or someone else did, you can open it easily to view its contents. The easiest way to open an XML file is to use a text editor, such as Notepad. Because the Code Editor has a friendlier appearance and it is available to you, you can use it. To open an XML file, on the main menu, you can click File -> Open File..., locate the file, and click Open.

After creating an XML file, one way you can use it is to display it in a grid-based window such as a spreadsheet.

An XML File in a Browser

Another way you can display an XML file is in a browser. Here is an example:

Preview

Visually Opening an XML File

If you are working in Microsoft Visual Studio, you can use it to open an XML file. To do this, you can use the File option on the main menu and click the Open option.

Programmatically Opening an XML File Using the DOM

At times, you will need to programmatically access an XML file. To support this operation, the XmlDocument class is equipped with a method named Load. It is available in various versions. One of the syntaxes used by this method is:

public virtual void Load(string filename);

This version takes as argument the name or path of the file. Here is an example of calling it:

private void Exercise_Load(object sender, EventArgs e)
{
    XmlDocument docMusicCollection = new XmlDocument();

    docMusicCollection.Load("music.xml");
}

In this case, the compiler would look for the file in the folder of the current application. You can also provide a complete path to the file. Either way, if the compiler doesn't find the file, it would throw a FileNotFoundException exception. For this reason, it is cautious to first check that the file exists before opening it. This can be done as follows:

using System.Xml;
using System.IO;

public class Exercise : System.Windows.Forms.Form
{
    public Exercise()
    {
        InitializeComponent();
    }

    private void Exercise_Load(object sender, EventArgs e)
    {
        XmlDocument docMusicCollection = new XmlDocument();

        string strFilename = "music.xml";

        if(File.Exists(strFilename))
            docMusicCollection.Load(strFilename);
        else
            MessageBox.Show("The file " + strFilename + " was not found",
                            "Music Collection",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

An alternative is to handle the exception yourself.

You can also use a Stream-based object to identify the file. To assist you with this, the XmlDocument class is equipped with another version of the Load() method whose syntax is:

public virtual void Load(Stream inStream);

This method expects a Stream type of object, such as a FileStream variable. Here is an example of calling it:

private void Exercise_Load(object sender, EventArgs e)
{
    XmlDocument docMusicCollection = new XmlDocument();
    string strFilename = "music.xml";
    FileStream fstMusic = null;

    if (File.Exists(strFilename))
    {
        fstMusic = new FileStream(strFilename,
                                  FileMode.Open,
                                  FileAccess.Read);
        docMusicCollection.Load(fstMusic);
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found",
                        "Music Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Reading an XML File

Reading the Text in the Document

An XML document is just text. That makes it very easy to read with human eyes. To help you programmatically read text, the .NET Framework provides many classes in the System.IO namespace. One of those classes is TextReader:

public abstract class TextReader : MarshalByRefObject, IDisposable

Since TextReader is an abstract class, you will need a class derived from it. A typical class you can use is StreamReader:

public class StreamReader : System.IO.TextReader

As a result, you can use a StreamReader object to read the content of an XML document. You would start as follows:

using System.Xml;

namespace VideoCollection
{
    public partial class Exercise : Form
    {
        public Exercise()
        {
            InitializeComponent();
        }

        private void btnDocument_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new XmlDocument();
            string strVideos = @"C:\Videos Collection\Videos.xml";

            if (File.Exists(strVideos) == true)
            {
                TextReader trVideos = new StreamReader(strVideos);
                
                // Use trVideos here
            }
        }
    }
}

Using an XML Text Reader

In your application, you will have to programmatically open and read XML files. This is also referred to as parsing (the parser parses the document). As one way to support reading an XML file, the .NET Framework provides an abstract class named XmlReader. It is the ancestor of classes that can read an XML file. One of the classes derived from XmlReader is called XmlTextReader. The XmlTextReader class provides the ability to read an XML file from the left to the right sides and from the top to the bottom sections. This class has very important characteristics you must remember:

To programmatically read an XML file, you can start by declaring a variable of type XmlTextReader using one of its constructors, including the default. To specify the file you want to open and read, you can use the constructor whose syntax is the following:

public XmlTextReader(string url);

When using this method, pass the name of the file or its path as argument. Here is an example:

private void Exercise_Load(object sender, EventArgs e)
{
    XmlDocument docMusicCollection = new XmlDocument();
    string strFilename = "music.xml";

    if (File.Exists(strFilename))
    {
        XmlTextReader rdrXml = new XmlTextReader(strFilename);
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found",
                        "Music Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

You can also identify a file using a Stream-based object. Once the object is ready, you can pass it to the following constructor of the class:

public XmlTextReader(Stream input);

Here is an example:

private void btnDocument_Click(object sender, EventArgs e)
{
    string strFilename = "music.xml";
    using( FileStream fstMusic = new FileStream(strFilename,
                                         FileMode.Open,
                                         FileAccess.Read);
    {
        if (File.Exists(strFilename))
        {
            XmlTextReader rdrMusic = new XmlTextReader(fstMusic);
        }
        else
            MessageBox.Show("The file " + strFilename + " was not found",
                            "Music Collection",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

To let you read the file, the XmlTextReader is equipped with a method named Read. Its syntax is:

public override bool Read();

As you may suspect, this method only tells you that it successfully read an item. It doesn't tell you what it read. As stated already, the XmlTextReader class scans a file in a left-right-top-down approach. When it has read something, it returns true. If it didn't or couldn't read something, it returns false. Therefore, you can call it to read an item. If it succeeds, it returns true. After reading that item, you can call it again to move to the next item. If there is a next item, it reads it and returns true. But, if there is no next item, the Read() method would not be able to read it and it would return false. In other words, you can ask the Read() method to continuously read the items as long as it returns true. Once it cannot read an item, you can ask it to stop. To perform this exercise, you can use either a while or a do...while loop. This would be done as follows:

private void Exercise_Load(object sender, EventArgs e)
{
    string strFilename = "music.xml";
    FileStream fstMusic = new FileStream(strFilename,
                                         FileMode.Open,
                                         FileAccess.Read);
    if (File.Exists(strFilename))
    {
        XmlTextReader rdrMusic = new XmlTextReader(fstMusic);

        do
        {
            // Read an item and return true
            // Continue reading as long as ...
        } while (rdrMusic.Read() == true); // ... as long as Read() returns true
        // Once Read() returns false, STOP!!!

        fstMusic.Close();
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found",
                        "Music Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

To identify what was read, the XmlTextReader provides methods appropriate for the different types of items that an XML file can contain. We will eventually review the types of items of a file.

Using a Stream

As we mentioned already, you can use a Stream-derived class to initiate a file, then use that Stream object as you see fit. This would start as follows:

using System.Xml;

namespace VideoCollection
{
    public partial class Exercise : Form
    {
        public Exercise()
        {
            InitializeComponent();
        }

        private void btnDocument_Click(object sender, EventArgs e)
        {
            var xdVideos = new XmlDocument();
            string strVideos = @"C:\Videos Collection\Videos.xml";

            if (File.Exists(strVideos) == true)
            {
                using (FileStream fsVideos = new FileStream(strVideos, FileMode.Open, FileAccess.Read))
                    
                    // Use fsVideos
            }
        }
    }
}

XML Well-Formed

Tag Creation

Earlier, we mentioned that XML worked through markups. A simple markup is made of a tag created between the left angle bracket "<" and the right angle bracket ">". Just creating a markup is not particularly significant. You must give it meaning. To do this, you can type a number, a date, or a string on the right side of the right angle bracket ">" symbol. The text on the right side of ">" is referred to as the item's text. It is also called a value.

After specifying the value of the markup, you must close it: this is a rule not enforced in HTML but must be respected in XML to make it "well-formed". To close a tag, use the same formula of creating a tag with the left angle bracke "<", the tag, and the right angle bracket ">" except that, between < and the tag, you must type a forward slash. The formula to use is:

<tag>some value</tag>

The item on the left side of the "some value" string, in this case <tag>, is called the opening or start-tag. The item on the right side of the "some value" string, in this case </tag>, is called the closing or end-tag. Like <tag> is a markup, </tag> also is called a markup.

With XML, you create your own tags with custom names. This means that a typical XML file is made of various items. Here is an example:

<title>The Distinguished Gentleman</title>
	<director>Jonathan Lynn</director><length>112 Minutes</length>

Tag Names

When creating your tags, there are various rules you must observe with regards to their names. Unlike HTML, XML is very restrictive with its rules. For example, unlike HTML but like C/C++/C#, XML is case-sensitive. This means that CASE, Case, and case are three different words. Therefore, from now on, you must pay close attention to what you write inside the < and the > delimiters.

Besides case sensitivity, there are some rules you must observe when naming the tags of your markups:

In future sections, we will learn that, with some markups, you can include non-readable characters between the angle brackets. In fact, you will need to pay close attention to the symbols you type in a markup. We will also see how some characters have special meanings.

The Root

Every XML document must have one particular tag that, either is the only tag in the file, or acts as the parent of all the other tags of the same document. This tag is called the root. Here is an example of a file that has only one tag:

<rectangle>A rectangle is a shape with 4 sides and 4 straight angles</rectangle>

This would produce:

XML in a Browser

If there are more than one tag in the XML file, one of them must serve as the parent or root. Otherwise, you would receive an error. Based on this rule, the following XML code is not valid:

<rectangle>A rectangle is a shape with 4 sides and 4 straight angles</rectangle>
<square>A square is a rectangle whose 4 sides are equal</square>

This would produce:

An ill-formed XML file in a Browser

 To correct this type of error, you can change one of the existing tags to act as the root. In the following example, the <rectangle> tag acts as the parent:

<rectangle>A rectangle is a shape with 4 sides and 4 straight angles
<square>A square is a rectangle whose 4 sides are equal</square></rectangle>

This would produce:

Good Nested Tags

Alternatively, you can create a tag that acts as the parent for the other tags. In the following example, the <geometry> tag acts as the parent of the <rectangle> and of the <square> tags:

<geometry><rectangle>A rectangle is a shape with 4 sides and 4 straight angles
</rectangle><square>A square is a rectangle whose 4 sides are equal</square></geometry>

This would produce:

Preview

As mentioned already, a good XML file should have a Document Type Declaration:

<?xml version="1.0" encoding="utf-8"?><geometry><rectangle>A rectangle 
is a shape with 4 sides and 4 straight angles</rectangle><square>A 
square is a rectangle whose 4 sides are equal</square></geometry>

To give you access to the root of an XML file, the XmlDocument class is equipped with a property named DocumentElement.

The Structure of an XML Tag

Empty Tags

We mentioned that, unlike HTML, every XML tag must be closed. We also saw that the value of a tag was specified on the right side of the right angle bracket of the start tag. In some cases, you will create a tag that doesn't have a value or, may be for some reason, you don't provide a value to it. Here is an example:

<dinner></dinner>

This type of tag is called an empty tag. Since there is no value in it, you may not need to provide an end tag but it still must be closed. Although this writing is allowed, an alternative is to close the start tag itself. To do this, between the tag name and the right angle bracket, type an empty space followed by a forward slash. Based on this, the above line can be written as follows:

<dinner />

Both produce the same result or accomplish the same role.

White Spaces

In the above example, we typed various items on the same line. If you are creating a long XML document, although creating various items on the same line is acceptable, this technique can make it (very) difficult to read. One way you can solve this problem is to separate tags with empty spaces. Here is an example:

<title>The Distinguished Gentleman</title> 
	<director>Jonathan Lynn</director>
		<length>112 Minutes</length>

Yet a better solution consists of typing each item on its own line. This would make the document easier to read. Here is an example:

<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
<length>112 Minutes</length>

All these are possible and acceptable because the XML parser doesn't consider the empty spaces or end of line. Therefore, to make your code easier to read, you can use empty spaces, carriage-return-line-feed combinations, or tabs inserted in various sections. All these are referred to as white spaces.

Nesting Tags

Most XML files contain more than one tag. We saw that a tag must have a starting point and a tag must be closed. One tag can be included in another tag: this is referred to as nesting. A tag that is created inside of another tag is said to be nested. A tag that contains another tag is said to be nesting. Consider the following example:

<smile>Please smile to the camera</smile>
<english>Welcome to our XML Class</english>
<french>Bienvenue à notre Classe XML</french>

In this example, you may want the english tag to be nested in the smile tag. To nest one tag inside of another, you must type the nested tag before the end-tag of the nesting tag. For example, if you want to nest the english tag in the smile tag, you must type the whole english tag before the </smile> end tag. Here is an example:

<Smile>Please smile to the camera<English>Welcome to our XML Class</English></Smile>

To make this code easier to read, you can use white spaces as follows:

<smile>Please smile to the camera
<english>Welcome to our XML Class</english>
</smile>

When a tag is nested, it must also be closed before its nesting tag is closed. Based on this rule, the following code is not valid:

<smile>Please smile to the camera
<english>Welcome to our XML Class
</smile>
</english>

The rule broken here is that the english tag that is nested in the the smile tag is not closed inside the smile tag but outside.

Once you have decided on the structure of your XML file, we saw that you can create it in memory using the XmlDocument.LoadXml() method. For example, the following XML code:

<?xml version="1.0" encoding="utf-8"?>
<music-collection>
    <album>
        <shelf-number>FJ-7264</shelf-number>
        <title>Symphony-Bantu</title>
        <artist>Vincent Nguini</artist>
        <copyright-year>1994</copyright-year>
        <publisher>Mesa Records</publisher>
    </album>
    <album>
        <shelf-number>MR-2947</shelf-number>
        <title>None</title>
        <artist>Debbie Gibson</artist>
        <copyright-year>1990</copyright-year>
        <publisher>Atlantic</publisher>
    </album>
</music-collection>

can be created in memory as follows:

using System.Xml;

namespace MusicCollection
{
    public partial class Exercise : Form
    {
        public Exercise()
        {
            InitializeComponent();
        }

        private void btnDocumentClick(object sender, EventArgs e)
        {
            XmlDocument docMusic = new XmlDocument();
            
            docMusic.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                             "<music-collection><album>" +
                             "<shelf-number>FJ-7264</shelf-number>" +
                             "<title>Symphony-Bantu</title>" +
                             "<artist>Vincent Nguini</artist>" +
                             "<copyright-year>1994</copyright-year>" +
                             "<publisher>Mesa Records</publisher></album>" +
                             "<album><shelf-number>MR-2947</shelf-number>" +
                             "<title>None</title><artist>Debbie Gibson</artist>" +
                             "<copyright-year>1990</copyright-year>" +
                             "<publisher>Atlantic</publisher>" +
                             "</album></music-collection>");
    }
}

Notice that the whole XML code can be created as one line of text and the code would be valid.

An XML Node

Introduction to XML Nodes

Consider the following example of an XML file named Videos.xml:

<?xml version="1.0" encoding="utf-8" ?>
<videos>
    <video>
        <title>The Distinguished Gentleman</title>
        <director>Jonathan Lynn</director>
        <length>112 Minutes</length>
        <format>DVD</format>
        <rating>R</rating>
    </video>
    <video>
        <title>Her Alibi</title>
        <director>Bruce Beresford</director>
        <length>94 Mins</length>
        <format>DVD</format>
        <rating>PG-13</rating>
    </video>
    <video>
        <title>Chalte Chalte</title>
        <director>Aziz Mirza</director>
        <length>145 Mins</length>
        <format>DVD</format>
        <rating>N/R</rating>
    </video>
</videos>

An XML file appears as an upside-down tree: it has a root (in this case <videos>), it can have branches (in this case <video>), and it can have leaves (an example in this case is <title>). As we have seen so far, all these objects are created using the same technique: a tag with a name (such as <title>) and an optional value. Based on their similarities, each of these objects is called a node.

To support nodes of an XML document, the .NET Framework provides a class named XmlNode:

public abstract class XmlNode : ICloneable, 
                                IEnumerable,
                                IXPathNavigable

The XmlNode class is the ancestor to all types of nodes. XmlNode is an abstract class without a constructor. Based on this, to get a node, you must have an object that would produce one and you can only retrieve a node from an (existing) object. Actually, because XmlNode is an abstract class, when you need a node object, you will use one of the classes derived from XmlNode, and there are many of them.

The XmlDocument class to which we were introduced earlier starts as follows:

public class XmlDocument : System.Xml.XmlNode

This means that the XmlDocument class is based on XmlNode; that is, XmlDocument is one of the numerous classes that derives from XmlNode.

Introduction to Node Types

To make XML as complete and as efficient as possible, it can contain various types of nodes. The categories or possible types of nodes are identified by an enumeration named XmlNodeType. If you use an XmlTextReader object to scan a file, when calling the Read() method, the class has a property named NodeType that allows you to identify the node that was read. NodeType is a read-only property of type XmlNodeType and it is declared as follows:

public override XmlNodeType NodeType { get; }

Therefore, when calling the XmlTextReader.Read() method, you can continuously check the value of the XmlTextReader.NodeType property to find out what type of node was just read, and then you can take an appropriate action.

Linking XML Nodes

We mentioned that the nodes of a XML document are organized as a tree, with a (one) root, branches, and leaves. Consider the following XML document:

<?xml version="1.0" encoding="utf-8"?>
<payrolls>
	<payroll>
		<payroll-number>100001</payroll-number>
		<employee-number>946-824</employee-number>
		<time-worked>
			<monday>8.00</monday>
			<tuesday>9.50</tuesday>
			<friday>6.50</friday>
		</time-worked>
	</payroll>
	<payroll>
		<payroll-number>100002</payroll-number>
		<employee-number>408-315</employee-number>
		<time-worked>
			<saturday>9.00</saturday>
			<sunday>9.00</sunday>
		</time-worked>
	</payroll>
	<payroll>
		<payroll-number>100003</payroll-number>
		<employee-number>720-482</employee-number>
		<time-worked>
			<monday>7.00</monday>
			<wednesday>7.00</wednesday>
			<friday>7.00</friday>
		</time-worked>
	</payroll>
</payrolls>

As we have already mentioned the root, branches, and leaves, you may be interested in the grouping of nodes. You can see that the nodes are put together where they share some type of neighborhood or family relationships. For example, you can see that sometimes a node has another node before or after it, or a node can found itself between two other nodes, and those nodes would be at the same level. This is where indentation is helpful in an XML document. When two or more nodes are nested in a node, those nodes are referred to as siblings. When performing operations on such nodes, you may need to identify their relationship to each other. As one way to assist you with this, the .NET Framework provides a tiny class named XmlLinkedNode:

public abstract class XmlLinkedNode : System.Xml.XmlNode

As you can see, XmlLinkedNode is an abstract class. It is derived from XmlNode which, as we saw already, too is abstract. This means that, when you need the functionality of the XmlLinkedNode class, you will use a class derived from it.

Practical LearningPractical Learning: Ending the Lesson


Home Copyright © 2005-2023, FunctionX Monday 06 December 2021 Next