Home

Introduction to XML Elements

Elements Fundamentals

Introduction

An element in an XML document is an object that begins with a start-tag, may contain a value, and may terminate with an end-tag. Based on this, the combination of a start-tag, the value, and the end-tag is called an element. An element can be more than that but for now, we will consider that an element is primarily characterized by a name and possibly a value.

To support XML elements, the System.Xml namespace provides the XmlElement class. To access an XML element, you can declare a variable of type XmlElement but the main purpose of this class is to get an element from a DOM object. For this reason, the XmlElement class doesn't have a constructor you can use. Instead, and as we will learn, the other classes have methods that produce an XmlElement element you can manipulate as necessary.

In the previous lesson, we saw that every XML file must have a root and we mentioned that you could use the XmlDocument.DocumentElement property to access it. This property is of type XmlElement and, to access it, you can declare an XmlElement variable and assign it this property. Here is an example:

File: 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>
----------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;

public class Exercise : System.Windows.Forms.Form
{
    Button btnDocument;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        btnDocument = new Button();
        btnDocument.Text = "Write";
        btnDocument.Location = new Point(12, 12);
        btnDocument.Click += new EventHandler(btnDocumentClick);

        Text = "Video Collection";
        StartPosition = FormStartPosition.CenterScreen;
        Controls.Add(btnDocument);
    }

    void btnDocumentClick(object sender, EventArgs e)
    {
        string Filename = "videos.xml";
        XmlDocument docVideo = new XmlDocument();

        if (File.Exists(Filename))
        {
            docVideo.Load(Filename);
            XmlElement elm = docVideo.DocumentElement;
        }
        else
            MessageBox.Show("The file " + Filename + " was not found",
                            "Video Collection",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

public class Program
{
    static int Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

An XML element is represented in the XmlNodeType enumeration as the Element member. When using the Read() method of an XmlTextReader object, to find out if the item being read is an element, you can check whether the member of the current XmlNodeType is Element. Here is an example:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        XmlTextReader rdrVideos = new XmlTextReader(Filename);

        do
        {
            switch (rdrVideos.NodeType)
            {
                case XmlNodeType.Element:
                    break;
            }
        } while (rdrVideos.Read());
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Practical LearningPractical Learning: Introducing XML Elements

  1. Start Microsoft Visual Studio if necessary and open the LambdaSquareApartments2 application from the previous lesson.
    If necessary, display the Employees form and double-click an unoccupied area of its body.
    Change the ShowEmployees method as follows:
    void ShowEmployees()
    {
        XmlDocument xdEmployees = new XmlDocument();
        string strFileName = "../../Employees.xml";
    
        if (File.Exists(strFileName))
        {
            xdEmployees.Load(strFileName);
            XmlElement xeEmployee = xdEmployees.DocumentElement;
        }
    }
  2. To create a new form, on the main menu, click Project -> Add Windows Form...
  3. Set the name to Apartments and click Add
  4. Design the form as follows:
     

    Lambda Square Apartments - Apartments

    Control (Name) Text Other Properties
    ListView List View lvwApartments   View: Details
    FullRowSelect: True
    GridLines: True
    Columns
    (Name) Text TextAlign Width
    colUnitCode Code   45
    colApartmentNumber Apart #   50
    colBedrooms Beds Right 40
    colBathrooms Baths Right 45
    colMonthlyRate Rent/Mth Right  
    colSecurityDeposit Deposit Right  
    colOccupancyStatus Status    
    Button Button btnNewApartment New Apartment...  
    Button Button btnClose Close  
  5. To create a new dialog box, in the Solution Explorer, right-click LambdaSquareApartment2 -> Add -> Windows Form
  6. Set the Name to TenantRegistrationEditor and press Enter
  7. Design the form as follows:
     

    Lambda Square Apartments - New Tenant Registration

    Control (Name) Text Other Properties
    Label Label   Registration Date:  
    DateTimePicker Date Time Picker dtpRegistrationDate   Modifiers: Public
    Label Label   Processed By AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Label   Employee #:  
    TextBox Text Box txtEmployeeNumber   Modifiers: Public
    TextBox Text Box txtEmployeeName    
    Label Label   Tenant Information AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Label   Tenant Code:  
    TextBox Text Box txtTenantCode   Modifiers: Public
    Label Label   First Name:  
    TextBox Text Box txtFirstName   Modifiers: Public
    Label Label   Last Name:  
    TextBox Text Box txtLastName   Modifiers: Public
    Label Label   Marital Status:  
    ComboBox Combo Box cbxMaritalsStatus   Modifiers: Public
    Items:
    Single
    Widow
    Married
    Divorced
    Separated
    Unspecified
    Label Label   Phone Number:  
    MaskedTextBox Masked Text Box txtPhone Number   Modifiers: Public
    Mask: (000) 000-0000
    Label Label   Number of Children  
    TextBox Text Box txtNumberOfChildren   Modifiers: Public
    TextAlign: Right
    Label Label   Email Address:  
    TextBox Text Box txtEmailAddress   Modifiers: Public
    Label Label   Apartment Allocation AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Label   Unit Code:  
    TextBox Text Box txtUnitCode   Modifiers: Public
    TextBox Text Box txtApartmentDetails   Multiline: True
    ScrollBars: Vertical
    Label Label   Rent Start Date:  
    DateTimePicker Date Time Picker dtpRentStartDate   Modifiers: Public
    Label Label   Registration Number:  
    TextBox Text Box txtRegistrationNumber   Modifiers: Public
    Button Button btnSubmit Submit  
    Button Button btnClose Close  
  8. To create a new form, on the main menu, click PROJECT -> Add Windows Form...
  9. Set the name to TenantsRegistrations and click Add
  10. Design the form as follows:
     

    Lambda Square Apartments - Tenants Registrations

    Control (Name) Text Other Properties
    ListView List View lvwRegistrations   View: Details
    FullRowSelect: True
    GridLines: True
    Columns
    (Name) Text TextAlign Width
    colRegistrationNumber Regist #   55
    colRegistrationDate Regist Date Center 70
    colEmployee Processed By   140
    colTenantCode Tenant Code Center 75
    colFirstName First Name   65
    colLastName Last Name   65
    colMaritalStatus Marital Status   80
    colNumberOfChildren # of Children Right 75
    colPhoneNumber Phone #   85
    colEmailAddress Email Address   150
    colApartment Apartment   368
    colRentStartDate Rent Start Date Center 90
    Button Button btnNewRegistration New Registration...  
    Button Button btnClose Close  
  11. To create a new dialog box, in the Solution Explorer, right-click LambdaSquareApartment2 -> Add -> Windows Form
  12. Set the Name to PaymentEditor and press Enter
  13. Design the form as follows:
     

    Lambda Square Apartments - New Payment

    Control (Name) Text Other Properties
    Label Label   Payment Date:  
    DateTimePicker Date Time Picker dtpPaymentDate   Modifiers: Public
    Label Label   Processed By AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Label   Employee #:  
    TextBox Text Box txtEmployeeNumber   Modifiers: Public
    TextBox Text Box txtEmployeeName    
    Label Label   Registration Information AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Label   Registration #:  
    TextBox Text Box txtRegistrationNumber   Modifiers: Public
    Label Label   Date Registered:  
    TextBox Text Box txtDateRegistered    
    Label Label   Rent Start Date:  
    TextBox Text Box txtRentStartDate    
    Label Label   Tenant:  
    TextBox Text Box txtTenantInformation    
    Label Label   Apartment Info:  
    MaskedTextBox Masked Text Box txtApartmentInformation   Multiline: True
    ScrollBars: Vertical
    Label Label   Payment Details AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Label   Payment Amount:  
    TextBox Text Box txtPaymentAmount   Modifiers: Public
    Label Label   Notes:  
    TextBox Text Box txtNotes   Modifiers: Public
    Multiline: True
    ScrollBars: Vertical
    Label Label   Receipt Number:  
    TextBox Text Box txtReceiptNumber   Modifiers: Public
    Button Button btnSubmit Submit  
    Button Button btnClose Close  
  14. To create a new form, on the main menu, click PROJECT -> Add Windows Form...
  15. Set the name to Payments and click Add
  16. Design the form as follows:
     

    Lambda Square Apartments - Payments

    Control (Name) Text Other Properties
    ListView List View lvwRegistrations   View: Details
    FullRowSelect: True
    GridLines: True
    Columns
    (Name) Text TextAlign Width
    colReceiptNumber Receipt #    
    colPaymentDate Pmt Date Center 70
    colEmployee Processed By   120
    colRegistrationInformation Registration Information   260
    colPaymentAmount Pmt Amt Right 55
    colNotes Notes   220
    Button Button btnPayment New Payment...  
    Button Button btnClose Close  
  17. Display the Lambda Square Apartments form and double-click an unoccupied area of the form
  18. Return to the form and double-click the Registrations button
  19. Return to the form and double-click the Payments button
  20. Return to the form and double-click the Apartments button
  21. Return to the form and double-click the Close button
  22. Change the document as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    
    namespace LambdaSquareApartments2
    {
        public partial class LambdaSquareApartments : Form
        {
            public LambdaSquareApartments()
            {
                InitializeComponent();
            }
    
    	private void btnEmployees_Click(object sender, EventArgs e)
    	{
    	    Employees empls = new Employees();
    	    empls.Show();
    	}
    
            private void LambdaSquareApartments_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Microsoft Visual C# Application Design\Lambda Square Apartments");
            }
    
            private void btnRegistrations_Click(object sender, EventArgs e)
            {
                TenantsRegistrations trs = new TenantsRegistrations();
                trs.Show();
            }
    
            private void btnPayments_Click(object sender, EventArgs e)
            {
                Payments pmts = new Payments();
                pmts.Show();
            }
    
            private void btnApartments_Click(object sender, EventArgs e)
            {
                Apartments units = new Apartments();
                units.Show();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }

The Name of an Element

The name of an element is the string that represents the tag. For example, in <Director>, the word Director is the name of the element. An element must have at least a start-tag. All of the tags we have seen so far were created as elements. When creating your elements, remember to follow the rules we defined for names.

The XmlElement class is equipped with the Name property that can be used to identify an existing element. Here is an example of accessing it:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        XmlElement elm = docVideo.DocumentElement;
        MessageBox.Show(elm.Name,
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

This would produce:

Video Collection

Notice that videos is returned as the name of the root element of the file. If calling the Read() method of an XmlTextReader object to scan a file, when you get to an element, you can find out its Name identity by accessing it. Here is an example:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        XmlTextReader rdrVideos = new XmlTextReader(Filename);

        do
        {
            switch (rdrVideos.NodeType)
            {
                case XmlNodeType.Element:
                    MessageBox.Show(rdrVideos.Name,
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
            }
        } while (rdrVideos.Read());
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

The Text or Value of an Element

The value of an element is the item displayed on the right side of the start-tag. It is also called the text of the element. In the case of <director>Jonathan Lynn</director>, the "Jonathan Lynn" string is the value of the director element. To support the text or value of an element, the XmlElement class is equipped with the Value property.

While the value of one element can be a number, the value of another element can be a date. Yet another element can use a regular string as its value. Consider the following example:

<?xml version="1.0" encoding="utf-8"?>
<videos>
    <video>
	<title>The Distinguished Gentleman</title>
	<director>Jonathan Lynn</director>
	<LengthInMinutes>112</LengthInMinutes>
	<format>DVD</format>
	<rating>R</rating>
	<price>14.95</price>
    </video>
    <video>
	<title>Her Alibi</title>
	<director>Bruce Beresford</director>
	<LengthInMinutes>94</LengthInMinutes>
	<format>VHS</format>
	<rating>PG-13</rating>
	<price>9.95</price>
    </video>
</videos>

Notice that the price elements contain numbers that look like currency values and the LengthInMinutes elements use an integer as value.

If you are using an XmlTextReader object to scan a file, when the Read() method gets to an element, you can find out what its value is by accessing this property. Here is an example:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        XmlTextReader rdrVideos = new XmlTextReader(Filename);

        do
        {
            switch (rdrVideos.NodeType)
            {
                case XmlNodeType.Text:
                    MessageBox.Show(rdrVideos.Value,
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
            }
        } while (rdrVideos.Read());
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

The value or text of an element is an object of type XmlText.

Empty Elements

An element may not have a value but only a name. Consider the following example:

<?xml version="1.0" encoding="utf-8"?>
<videos>
  <video>
    <title>The Distinguished Gentleman</title>
    <director>Jonathan Lynn</director>
  </video>
</videos>

In this case, the video element doesn't have a value. It is called an empty element. When a tag is empty, the Value property of its XmlElement object would return an empty value.

Character Entities in an Element Value

Besides the obvious types of values, you may want to display special characters as values of elements. Consider the following example:

<?xml version="1.0" encoding="utf-8" ?>
<Employees>
    <Employee>
	<FullName>Sylvie <Bellie> Aronson</FullName>
	<Salary>25.64</Salary>
	<DepartmentID>1</DepartmentID>
    </Employee>
    <Employee>
	<FullName>Bertrand Yamaguchi</FullName>
	<Salary>16.38</Salary>
	<DepartmentID>4</DepartmentID>
    </Employee>
</Employees>

If you try using this XML document, for example, if you try displaying it in a browser, you would receive an error:

The reason is that when the parser reaches the <FullName>Sylvie <Bellie> Aronson</FullName> line, it thinks that <Bellie> is a tag but then <Bellie> is not closed. The parser concludes that the document is not well-formed, that there is an error. For this reason, to display a special symbol as part of a value, you can use its character code. For example, the < (less than) character is represented with &lt and the > (greater than) symbol can be used with &gt;. Therefore, the above code can be corrected as follows:

<?xml version="1.0" encoding="utf-8" ?>
<Employees>
    <Employee>
	<FullName>Sylvie &lt;Bellie&gt; Aronson</FullName>
	<Salary>25.64</Salary>
	<DepartmentID>1</DepartmentID>
    </Employee>
    <Employee>
	<FullName>Bertrand Yamaguchi</FullName>
	<Salary>16.38</Salary>
	<DepartmentID>4</DepartmentID>
    </Employee>
</Employees>

This would produce:

Here is a list of other codes you can use for special characters:

Code Symbol Code Symbol Code Symbol Code Symbol Code Symbol
&apos; ' &#067; C &#106; j &#179; ³ &#218; Ú
&lt; < &#068; D &#107; k &#180; ´ &#219; Û
&gt; > &#069; E &#108; l &#181; µ &#220; Ü
&amp; & &#070; F &#109; m &#182; &#221; Ý
&quot; " &#071; G &#110; n &#183; · &#222; Þ
&#033; ! &#072; H &#111; o &#184; ¸ &#223; ß
&#034; " &#073; I &#112; p &#185; ¹ &#224; à
&#035; # &#074; J &#113; q &#186; º &#225; á
&#036; $ &#075; K &#114; r &#187; » &#226; â
&#037; % &#076; L &#115; s &#188; ¼ &#227; ã
&#038; & &#077; M &#116; t &#189; ½ &#228; ä
&#039; ' &#078; N &#117; u &#190; ¾ &#229; å
&#040; ( &#079; O &#118; v &#191; ¿ &#230; æ
&#041; ) &#080; P &#119; w &#192; À &#231; ç
&#042; * &#081; Q &#120; x &#193; Á &#232; è
&#043; + &#082; R &#121; y &#194; Â &#233; é
&#044; , &#083; S &#122; z &#195; Ã &#234; ê
&#045; - &#084; T &#123; { &#196; Ä &#235; ë
&#046; . &#085; U &#125; } &#197; Å &#236; ì
&#047; / &#086; V &#126; ~ &#198; Æ &#237; í
&#048; 0 &#087; W &#160; empty &#199; Ç &#238; î
&#049; 1 &#088; X &#161; ¡ &#200; È &#239; ï
&#050; 2 &#089; Y &#162; ¢ &#201; É &#240; ð
&#051; 3 &#090; Z &#163; £ &#202; Ê &#241; ñ
&#052; 4 &#091; [ &#164; ¤ &#203; Ë &#242; ò
&#053; 5 &#092; \ &#165; ¥ &#204; Ì &#243; ó
&#054; 6 &#093; ] &#166; ¦ &#205; Í &#244; ô
&#055; 7 &#094; ^ &#167; § &#206; Î &#245; õ
&#056; 8 &#095; _ &#168; ¨ &#207; Ï &#246; ö
&#057; 9 &#096; ` &#169; © &#208; Ð &#247; ÷
&#058; : &#097; a &#170; ª &#209; Ñ &#248; ø
&#059; ; &#098; b &#171; « &#210; Ò &#249; ù
&#060; < &#099; c &#172; ¬ &#211; Ó &#250; ú
&#061; = &#100; d &#173; ­ &#212; Ô &#251; û
&#062; > &#101; e &#174; ® &#213; Õ &#252; ü
&#063; ? &#102; f &#175; ¯ &#214; Ö &#253; ý
&#064; @ &#103; g &#176; ° &#215; × &#254; þ
&#065; A &#104; h &#177; ± &#216; Ø &#255; ÿ
&#066; B &#105; i &#178; ² &#217; Ù &#256; Ā

There are still other codes to include special characters in an XML file.

Identifying the Markup of a Node

The Inner Text of a node

In the previous sections, we have seen how to create a tag to produce a node. We also saw that a node could be placed inside of another node. The combined text of the values of the children of a node is available through its XmlNode.InnerText property which is declared as follows:

public virtual string InnerText { get; set; }

This property concatenates the values of the children of the node that called them but doesn't include their markups. Here is an example:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;

public class Exercise : System.Windows.Forms.Form
{
    Button btnDocument;
    RichTextBox rchDocument;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        btnDocument = new Button();
        btnDocument.Text = "Document";
        btnDocument.Location = new Point(12, 12);
        btnDocument.Click += new EventHandler(btnDocumentClick);

        rchDocument = new RichTextBox();
        rchDocument.Location = new Point(12, 40);
        rchDocument.Width = 200;

        Text = "Video Collection";
        StartPosition = FormStartPosition.CenterScreen;
        Controls.Add(btnDocument);
        Controls.Add(rchDocument);
    }

    void btnDocumentClick(object sender, EventArgs e)
    {
        XmlDocument docVideo = new XmlDocument();
        string Filename = "videos.xml";

        if (File.Exists(Filename))
        {
            docVideo.Load(Filename);
            XmlElement elm = docVideo.DocumentElement;
            rchDocument.Text = elm.InnerText;
        }
        else
            MessageBox.Show("The file " + Filename + " was not found",
                            "Video Collection",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

public class Program
{
    static int Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

This would produce:

Video Collection

Notice that this property produces all values of the children of a node in one block. We already saw how to access each value of the children of a node by calling the XmlTextReader.Read() method and get its Text.

The Outer XML Code of a Node

If you want to get a node, its markup, its child(ren) and its(their) markup(s), you can access its XmlNode.OuterXml property which is declared as follows:

public virtual string OuterXml { get; }

Here is an example:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;

public class Exercise : System.Windows.Forms.Form
{
    Button btnDocument;
    RichTextBox rchDocument;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        btnDocument = new Button();
        btnDocument.Text = "Document";
        btnDocument.Location = new Point(12, 12);
        btnDocument.Click += new EventHandler(btnDocumentClick);

        rchDocument = new RichTextBox();
        rchDocument.Location = new Point(12, 40);
        rchDocument.Size = new Size(260, 150);

        Text = "Video Collection";
        StartPosition = FormStartPosition.CenterScreen;
        Controls.Add(btnDocument);
        Controls.Add(rchDocument);
    }

    void btnDocumentClick(object sender, EventArgs e)
    {
        XmlDocument docVideo = new XmlDocument();
        string Filename = "videos.xml";

        if (File.Exists(Filename))
        {
            docVideo.Load(Filename);
            XmlElement elm = docVideo.DocumentElement;
            rchDocument.Text = elm.OuterXml;
        }
        else
            MessageBox.Show("The file " + Filename + " was not found",
                            "Video Collection",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

public class Program
{
    static int Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

This would produce:

Video Collection

The Inner XML Code of a Node

If you want only the markup(s) of the child(ren) excluding the parent, access its XmlNode.InnerXml property which is declared as follows:

public virtual string InnerXml { get; set; }

Here is an example:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        XmlElement elm = docVideo.DocumentElement;
        rchDocument.Text = elm.InnerXml;
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

This would produce:

Video Collection

The  Child Nodes of  a Node

Introduction

As mentioned already, one node can be nested inside of another. A nested node is called a child of the nesting node. This also implies that a node can have as many children as necessary, making them child nodes of the parent node. Once again, consider our videos.xml example:

<?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>

The title and the director nodes are children of the video node. The video node is the parent of both the title and the director nodes.

A Collection of XML Nodes

As you may know already, an XML document usually contains many nodes. To consider a collection of nodes, the .NET Framework provides a class named XmlNodeList. It starts as follows:

public abstract class XmlNodeList : IEnumerable, 
				    IDisposable

We will review the characteristics of this class in later sections.

Linking the Nodes

To manage the relationships among the nodes of an XML document, the .NET Framework provides a class named XmlLinkedNode:

public abstract class XmlLinkedNode : XmlNode

As a result, many classes derive from XmlLinkedNode. That's the case for the  XmlElement class:

public class XmlElement : XmlLinkedNode

A Collection of Child Nodes

To support the child nodes of a particular node, the XmlNode class is equipped with a property named ChildNodes. That property is of type XmlNodeList. The property is declared as follows:

public virtual XmlNodeList ChildNodes { get; }

When this property is used, it produces an XmlNodeList list, which is a collection of all nodes that share the same parent. Each item in the collection is of type XmlNode. To give you the number of nodes on an XmlNodeList collection, the class is equipped with a property named Count. Here is an example of using it:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        XmlElement elm = docVideo.DocumentElement;
        XmlNodeList lstVideos = elm.ChildNodes;

        MessageBox.Show("The root element contains " +
                        lstVideos.Count + " nodes",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

This would produce:

Videos

You can also use the Count property in a for loop to visit the members of the collection.

Practical LearningPractical Learning: Introducing Child Nodes

  1. Return to the document code of the Employees form.
    Change the ShowEmployees method as follows:
    void ShowEmployees()
    {
        XmlDocument xdEmployees = new XmlDocument();
        string strFileName = "../../Employees.xml";
    
        if (File.Exists(strFileName))
        {
            xdEmployees.Load(strFileName);
            XmlElement xeEmployee = xdEmployees.DocumentElement;
            XmlNodeList xnlEmployees = xeEmployee.ChildNodes;
        }
    }
  2. On the Standard toolbar, click the Save All button Save All

Accessing a Node in a Collection

The children of a node, that is, the members of a ChildNodes property, or the members of an XmlNodeList collection, can be located each by an index. The first node has an index of 0, the second has an index of 1, an so on. To give you access to a node of the collection, the XmlNodeList class is equipped with an indexed property and a method named Item. Both produce the same result. For example, if a node has three children, to access the third, you can apply an index of 2 to its indexed property. Here is an example:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        XmlElement elm = docVideo.DocumentElement;
        XmlNodeList lstVideos = elm.ChildNodes;

        MessageBox.Show(lstVideos[2].InnerText,
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Videos

You can also use the Item() method to get the same result. Using a for loop, you can access each node and display the values of its children as follows:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        XmlElement elm = docVideo.DocumentElement;
        XmlNodeList lstVideos = elm.ChildNodes;

        for (int i = 0; i < lstVideos.Count; i++)
            MessageBox.Show(lstVideos[i].InnerText,
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Videos

Videos

Videos

Instead of using the indexed property, the XmlNodeList class implements the IEnumerable interface. This allows you to use a foreach loop to visit each node of the collection. Here is an example:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        XmlElement elm = docVideo.DocumentElement;
        XmlNodeList lstVideos = elm.ChildNodes;

        foreach (XmlNode node in lstVideos)
            MessageBox.Show(node.InnerText,
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

To better manage and manipulate the nodes of a collection of nodes, you must be able to access the desired node. The XmlNode class combined with the XmlNodeList class provide various means of getting to a node and taking the appropriate actions.

The Parent of a Node

Not all nodes have children, obviously. For example, the title node of our videos.xml file does not have children. To find out whether a node has children, check its HasChildNodes Boolean property that is declared as follows:

public virtual bool HasChildNodes { get; }

If a node is a child, to get its parent, you can access its ParentNode property.

The First Child Node

The children of a nesting node are also recognized by their sequence. For our videos.xml file, the first line is called the first child of the DOM. This would be:

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

After identifying or locating a node, the first node that immediately follows it is referred to as its first child. In our videos.xml file, the first child of the first video node is the <title>The Distinguished Gentleman</title> element. The first child of the second <video> node is <title>Her Alibi</title>.

In the .NET Framework, the first child of a node can be retrieved by accessing the XmlNode.FirstChild property declared as follows:

public virtual XmlNode FirstChild { get; }

In the following example, every time the parser gets to a video node, it displays the value of it first child:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;

public class Exercise : System.Windows.Forms.Form
{
    Button btnDocument;
    ListBox lbxVideos;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        btnDocument = new Button();
        btnDocument.Text = "Document";
        btnDocument.Location = new Point(12, 12);
        btnDocument.Click += new EventHandler(btnDocumentClick);

        lbxVideos = new ListBox();
        lbxVideos.Location = new Point(12, 40);
        lbxVideos.Size = new Size(200, 60);

        Text = "Video Collection";
        StartPosition = FormStartPosition.CenterScreen;
        Controls.Add(btnDocument);
        Controls.Add(lbxVideos);
    }

    void btnDocumentClick(object sender, EventArgs e)
    {
        XmlDocument docVideo = new XmlDocument();
        string Filename = "videos.xml";

        if (File.Exists(Filename))
        {
            docVideo.Load(Filename);
            XmlElement elm = docVideo.DocumentElement;
            XmlNodeList lstVideos = elm.ChildNodes;

            foreach (XmlNode node in lstVideos)
                lbxVideos.Items.Add(node.FirstChild.InnerText);
        }
        else
            MessageBox.Show("The file " + Filename + " was not found",
                            "Video Collection",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

public class Program
{
    static int Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

This would produce:

Video Collection

In this example, we started our parsing on the root node of the document. At times, you will need to consider only a particular node, such as the first child of a node. For example, you may want to use only the first child of the root. To get it, you can access the FirstChild property of the DocumentElement object of the DOM. Once you get that node, you can then do what you judge necessary. In the following example, only the values of the child nodes of the first child of the root are displayed:

private void btnDocumentClick(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string Filename = "videos.xml";

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        XmlNode node = docVideo.DocumentElement.FirstChild;
        XmlNodeList lstVideos = node.ChildNodes;

        foreach (XmlNode child in node.ChildNodes)
            lbxVideos.Items.Add(child.InnerText);
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

This would produce:

Video Collection

Consider the following modification of the Videos.xml file:

<?xml version="1.0" encoding="utf-8" ?>
<Videos>
    <Video>
	<Title>The Distinguished Gentleman</Title>
	<Director>Jonathan Lynn</Director>
	<CastMembers>
	    <Actor>Eddie Murphy</Actor>
	    <Actor>Lane Smith</Actor>
	    <Actor>Sheryl Lee Ralph</Actor>
	    <Actor>Joe Don Baker</Actor>
	    <Actor>Victoria Rowell</Actor>
	</CastMembers>
	<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>

Remember that when using a for or a foreach loops applied to an XmlNodeList collection, each node that you access is a complete XmlNode object and may have children. This means that you can further get the ChildNodes node of any node. Here is an example that primarily scans the nodes but looks for one whose name is CastMembers:

private void btnDocumentClick(object sender, EventArgs e)
{
    string Filename = "videos.xml";
    XmlDocument docVideo = new XmlDocument();

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        // Locate the root node and 
        // get a reference to its first child
        XmlNode node = docVideo.DocumentElement.FirstChild;
        // Create a list of the child nodes of 
        // the first node under the root
        XmlNodeList lstVideos = node.ChildNodes;

        // Visit each node
        for (int i = 0; i < lstVideos.Count; i++)
        {
            // Look for a node named CastMembers
            if (lstVideos[i].Name == "CastMembers")
            {
                // Once/if you find it,
                // 1. Access its first child
                // 2. Create a list of its child nodes
                XmlNodeList lstActors =
                    lstVideos[i].ChildNodes;
                // Display the values of the nodes
                for (int j = 0; j < lstActors.Count; j++)
                    lbxVideos.Items.Add(lstActors[j].InnerText);
            }
        }
    }
    else
       MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

This would produce:

Video Collection

As we have learned that a node or a group of nodes can be nested inside of another node. When you get to a node, you may know or find out that it has children. You may then want to consider only the first child. Here is an example:

private void btnDocumentClick(object sender, EventArgs e)
{
    string Filename = "videos.xml";
    XmlDocument docVideo = new XmlDocument();

    if (File.Exists(Filename))
    {
        docVideo.Load(Filename);
        // Locate the root node and 
        // get a reference to its first child
        XmlNode node = docVideo.DocumentElement.FirstChild;
        // Create a list of the child nodes of 
        // the first node under the root
        XmlNodeList lstVideos = node.ChildNodes;

        // Visit each node
        for (int i = 0; i < lstVideos.Count; i++)
        {
            // Look for a node named CastMembers
            if (lstVideos[i].Name == "CastMembers")
            {
                // Once/if you find it,
                // 1. Access its first child
                // 2. Create a list of its child nodes
                XmlNodeList lstActors =
                    lstVideos[i].FirstChild.ChildNodes;
                // Display the value of its first child node
                for (int j = 0; j < lstActors.Count; j++)
                    lbxVideos.Items.Add(lstActors[j].InnerText);
            }
        }
    }
    else
        MessageBox.Show("The file " + Filename + " was not found",
                        "Video Collection",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

This would produce:

Video Collection

Practical LearningPractical Learning: Accessing the First Child Node

  1. Display the Tenant Registration Editor form and click the Employee # text box
  2. On the Properties window, click the Events button and double-click Leave
  3. Implement the event as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    
    namespace LambdaSquareApartments2
    {
        public partial class TenantRegistrationEditor : Form
        {
            public TenantRegistrationEditor()
            {
                InitializeComponent();
            }
    
            private void txtEmployeeNumber_Leave(object sender, EventArgs e)
            {
                XmlDocument docEmployees = new XmlDocument();
                string strFileName = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Employees.xml";
    
                if (File.Exists(strFileName))
                {
                    docEmployees.Load(strFileName);
                    XmlElement xeEmployee = docEmployees.DocumentElement;
                    XmlNodeList lstEmployees = xeEmployee.ChildNodes;
    
                    foreach(XmlNode xnEmployee in lstEmployees)
                    {
                        if( xnEmployee.FirstChild.InnerText == txtEmployeeNumber.Text)
                        {
                        }
                    }
                }
            }
        }
    }

The Last Child Node

As opposed to the first child, the child node that immediately precedes the end-tag of the parent node is called the last child. To get the last child of a node, you can access its XmlNode.LastChild property that is declared as follows:

public virtual XmlNode LastChild { get; }

The Siblings of a Node

The child nodes that are nested in a parent node and share the same level are referred to as siblings. Consider the above file: Director, CastMembers, and Length are child nodes of the Video node but the Actor node is not a child of the Video node. Consequently, Director, CastMembers, and Length are siblings. Obviously, to get a sibling, you must first have a node.

To access the sibling of a node, you can use its XmlNode.NextSibling property, which is declared as follows:

public virtual XmlNode NextSibling { get; }

Consider the following XML document:

<?xml version="1.0" encoding="utf-8"?>
<Properties>
	<Property>
		<PropertyCode>724-795</PropertyCode>
		<PropertyType>Apartment</PropertyType>
		<Bedrooms>1</Bedrooms>
		<Bathrooms>1</Bathrooms>
		<MonthlyRent>925</MonthlyRent>
		<Status>Occupied</Status>
	</Property>
	<Property>
		<PropertyCode>296-283</PropertyCode>
		<PropertyType>Apartment</PropertyType>
		<Bedrooms>2</Bedrooms>
		<Bathrooms>1</Bathrooms>
		<MonthlyRent>1150.50</MonthlyRent>
		<Status>Available</Status>
	</Property>
</Properties>

Here are examples of using the NextSibling property:

private void SolasPropertyRental_Load(object sender, EventArgs e)
{
    string Filename = "Properties.xml";
    XmlDocument docProperties = new XmlDocument();

    if (File.Exists(Filename))
    {
        docProperties.Load(Filename);
        XmlElement elmProperty = docProperties.DocumentElement;
        XmlNodeList lstProperties = elmProperty.ChildNodes;

        foreach(XmlNode node in lstProperties)
        {
            ListViewItem lviProperty = new ListViewItem(node.FirstChild.InnerText); // Property code

            lviProperty.SubItems.Add(node.FirstChild.NextSibling.InnerText); // Property Type
            lviProperty.SubItems.Add(node.FirstChild.NextSibling.NextSibling.InnerText); // Bedrooms
            lviProperty.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.InnerText); // Bathrooms
            lviProperty.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Monthly Rent
            lviProperty.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Status
            lvwProperties.Items.Add(lviProperty);
        }
    }
    else
        MessageBox.Show("The " + Filename + " file was not found");
}

Practical LearningPractical Learning: Using the Siblings of an XML Node

  1. Display the Employees form
  2. Right-click its body and click View Code
  3. Change the document as follows:
    using System;sing System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    
    namespace LambdaSquareApartments2
    {
        public partial class Employees : Form
        {
            public Employees()
            {
                InitializeComponent();
            }
    
            void ShowEmployees()
            {
                XmlDocument xdEmployees = new XmlDocument();
                string strFileName = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Employees.xml";
    
                if (File.Exists(strFileName))
                {
                    lvwEmployees.Items.Clear();
    
                    xdEmployees.Load(strFileName);
                    XmlElement xeEmployee = xdEmployees.DocumentElement;
                    XmlNodeList xnlEmployees = xeEmployee.ChildNodes;
    
                    foreach (XmlNode node in xnlEmployees)
                    {
                        ListViewItem lviEmployee = new ListViewItem(node.FirstChild.InnerText); // Employee Number
    
                        lviEmployee.SubItems.Add(node.FirstChild.NextSibling.InnerText); // First Name
                        lviEmployee.SubItems.Add(node.FirstChild.NextSibling.NextSibling.InnerText); // Last Name
                        lviEmployee.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.InnerText); // Title
    
                        lvwEmployees.Items.Add(lviEmployee);
                    }
                }
            }
    
            private void Employees_Load(object sender, EventArgs e)
            {
                ShowEmployees();
            }
        }
    }}
  4. Display the Apartments form and double-click an unoccupied area of its body
  5. Change the document as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    
    namespace LambdaSquareApartments2
    {
        public partial class Apartments : Form
        {
            public Apartments()
            {
                InitializeComponent();
            }
    
            void ShowProperties()
            {
                XmlDocument docApartments = new XmlDocument();
                string strFileName = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Apartments.xml";
    
                if (File.Exists(strFileName))
                {
                    lvwApartments.Items.Clear();
    
                    docApartments.Load(strFileName);
                    XmlElement elmApartment = docApartments.DocumentElement;
                    XmlNodeList lstApartments = elmApartment.ChildNodes;
    
                    foreach (XmlNode node in lstApartments)
                    {
                        ListViewItem lviApartment = new ListViewItem(node.FirstChild.InnerText); // Unit Code
    
                        lviApartment.SubItems.Add(node.FirstChild.NextSibling.InnerText); // Apartment Number
                        lviApartment.SubItems.Add(node.FirstChild.NextSibling.NextSibling.InnerText); // Bedrooms
                        lviApartment.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.InnerText); // Bathrooms
                        lviApartment.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Monthly Rate
                        lviApartment.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // SecurityDeposit
                        lviApartment.SubItems.Add(node.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Occupancy Status
    
                        lvwApartments.Items.Add(lviApartment);
                    }
                }
            }
    
            private void Apartments_Load(object sender, EventArgs e)
            {
                ShowProperties();
            }
        }
    }
  6. Display the Tenant Registration Editor form and click the Employee # text box
  7. In the Events section of the Properties window, double-click Leave
  8. Implement the event as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    
    namespace LambdaSquareApartments2
    {
        public partial class TenantRegistrationEditor : Form
        {
            public TenantRegistrationEditor()
            {
                InitializeComponent();
            }
    
            private void txtEmployeeNumber_Leave(object sender, EventArgs e)
            {
                bool employeeFound = false;
                XmlDocument docEmployees = new XmlDocument();
                string strFileName = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Employees.xml";
    
                if (File.Exists(strFileName))
                {
                    docEmployees.Load(strFileName);
                    XmlElement xeEmployee = docEmployees.DocumentElement;
                    XmlNodeList lstEmployees = xeEmployee.ChildNodes;
    
                    foreach(XmlNode xnEmployee in lstEmployees)
                    {
                        if( xnEmployee.FirstChild.InnerText == txtEmployeeNumber.Text)
                        {
                            employeeFound = true;
                            txtEmployeeName.Text = xnEmployee.FirstChild.NextSibling.InnerText + "(" +
                                                   xnEmployee.FirstChild.NextSibling.NextSibling.InnerText + ")";
                        }
                    }
    
                    if (employeeFound == false)
                    {
                        MessageBox.Show("There is no employee with that number.",
                                        "Lambda Square Apartments",
                                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
                else
                    MessageBox.Show("There is no list of employees to check.",
                                        "Lambda Square Apartments",
                                        MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
  9. Return to the Tenant Registration Editor form and click the Unit Code text box
  10. In the Events section of the Properties window, double-click Leave
  11. Implement the event as follows: 
    private void txtUnitCode_Leave(object sender, EventArgs e)
    {
        bool apartmentFound = false;
        XmlDocument xdApartments = new XmlDocument();
        string strFileName = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Apartments.xml";
    
        if (File.Exists(strFileName))
        {
            xdApartments.Load(strFileName);
            XmlElement xeApartment = xdApartments.DocumentElement;
            XmlNodeList xnlProperties = xeApartment.ChildNodes;
    
            foreach(XmlNode xnApartment in xnlProperties)
            {
                if (xnApartment.FirstChild.InnerText == txtUnitCode.Text)
                {
                    apartmentFound = true;
                    txtApartmentDetails.Text = "Bedroom(s):\t" + xnApartment.FirstChild.NextSibling.InnerText + Environment.NewLine +
                                               "Bathroom(s):\t" + xnApartment.FirstChild.NextSibling.NextSibling.InnerText + Environment.NewLine +
                                               "Monthly Rent:\t" + xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.InnerText + "\\month\n" + Environment.NewLine +
                                               "Security Deposit:\t " + xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText;
                }
            }
    
            if (apartmentFound == false)
            {
                MessageBox.Show("There is no apartment with that unit code.",
                            "Lambda Square Apartments",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtApartmentDetails.Text = "";
            }
        }
        else
            MessageBox.Show("There is no list of properties to check.",
                            "Lambda Square Apartments",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
  12. Display the Tenants Registrations form and double-click an unoccupied area of its body
  13. Change the document as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    
    namespace LambdaSquareApartments2
    {
        public partial class TenantsRegistrations : Form
        {
            public TenantsRegistrations()
            {
                InitializeComponent();
            }
    
            void ShowRentalRegistrations()
            {
                XmlDocument xdEmployees = new XmlDocument();
                XmlDocument xdApartments = new XmlDocument();
                XmlDocument xdRegistrations = new XmlDocument();
                string strEmployeesFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Employees.xml";
                string strApartmentsFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Apartments.xml";
                string strTenantsRegistrationsFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\TenantsRegistrations.xml";
    
                if (File.Exists(strTenantsRegistrationsFile))
                {
                    lvwRegistrations.Items.Clear();
    
                    xdEmployees.Load(strEmployeesFile);
                    xdApartments.Load(strApartmentsFile);
                    xdRegistrations.Load(strTenantsRegistrationsFile);
                    XmlElement xeEmployee = xdEmployees.DocumentElement,
                               xeApartment = xdApartments.DocumentElement,
                               xeRegistration = xdRegistrations.DocumentElement;
                    XmlNodeList xnlEmployees = xeEmployee.ChildNodes,
                                xnlApartments = xeApartment.ChildNodes,
                                xnlRegistrations = xeRegistration.ChildNodes;
    
                    foreach (XmlNode xnRegistration in xnlRegistrations)
                    {
                        ListViewItem lviRegistration = new ListViewItem(xnRegistration.FirstChild.InnerText); // Registration Number
    
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.InnerText); // Registration Date
    
                        foreach (XmlNode xnEmployee in xnlEmployees)
                        {
                            if (xnEmployee.FirstChild.InnerText == xnRegistration.FirstChild.NextSibling.NextSibling.InnerText)
                            {
                                lviRegistration.SubItems.Add(xnEmployee.FirstChild.InnerText + ": " + xnEmployee.FirstChild.NextSibling.InnerText + " " + xnEmployee.FirstChild.NextSibling.NextSibling.InnerText); // Employee Number
                                break;
                            }
                        }
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.InnerText); // Tenant Code
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // First Name
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Last Name
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Marital Status
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Number of Children
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Phone Number
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Email Address
    
                        foreach (XmlNode xnApartment in xnlApartments)
                        {
                            if (xnApartment.FirstChild.InnerText == xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                            {
                                lviRegistration.SubItems.Add("Apart #: " +
                                                             xnApartment.FirstChild.NextSibling.InnerText +
                                                             ", " + xnApartment.FirstChild.NextSibling.NextSibling.InnerText + " bedroom(s), " +
                                                             xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.InnerText + " bathroom(s), " +
                                                             "Rent: " + xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + "/month, " +
                                                             "Deposit: " + xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Employee Number
                                break;
                            }
                        }
    
                        lviRegistration.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Rent Start Date
                        lvwRegistrations.Items.Add(lviRegistration);
                    }
                }
            }
    
            private void TenantsRegistrations_Load(object sender, EventArgs e)
            {
                ShowRentalRegistrations();
            }
        }
    }
  14. Return to the Tenants Registrations form and double-click the New Registration button
  15. Implement the event as follows:
    private void btnNewRegistration_Click(object sender, EventArgs e)
    {
        int iRegistrationNumber = 1000;
        XmlDocument xdRegistrations = new XmlDocument();
        TenantRegistrationEditor editor = new TenantRegistrationEditor();
        string strTenantsRegistrationsFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\TenantsRegistrations.xml";
    
        if (File.Exists(strTenantsRegistrationsFile))
        {
            xdRegistrations.Load(strTenantsRegistrationsFile);
            XmlElement xeRegistration = xdRegistrations.DocumentElement;
            XmlNodeList xnlRegistrations = xeRegistration.ChildNodes;
    
            foreach (XmlNode xnRegistration in xnlRegistrations)
                iRegistrationNumber = int.Parse(xnRegistration.FirstChild.InnerText);
        }
    
        editor.txtRegistrationNumber.Text = (iRegistrationNumber + 1).ToString();
        editor.ShowDialog();
        ShowRentalRegistrations();
    }
  16. Display the Payment Editor and click the Employee # text box
  17. In the Events section of the Properties window, double-click Leave
  18. Implement the event as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    
    namespace LambdaSquareApartments2
    {
        public partial class PaymentEditor : Form
        {
            public TenantRegistrationEditor()
            {
                InitializeComponent();
            }
    
            private void txtEmployeeNumber_Leave(object sender, EventArgs e)
            {
                bool employeeFound = false;
                XmlDocument docEmployees = new XmlDocument();
                string strFileName = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Employees.xml";
    
                if (File.Exists(strFileName))
                {
                    docEmployees.Load(strFileName);
                    XmlElement xeEmployee = docEmployees.DocumentElement;
                    XmlNodeList lstEmployees = xeEmployee.ChildNodes;
    
                    foreach(XmlNode xnEmployee in lstEmployees)
                    {
                        if( xnEmployee.FirstChild.InnerText == txtEmployeeNumber.Text)
                        {
                            employeeFound = true;
                            txtEmployeeName.Text = xnEmployee.FirstChild.NextSibling.InnerText + "(" +
                                                   xnEmployee.FirstChild.NextSibling.NextSibling.InnerText + ")";
                        }
                    }
    
                    if (employeeFound == false)
                    {
                        MessageBox.Show("There is no employee with that number.",
                                        "Lambda Square Apartments",
                                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
                else
                    MessageBox.Show("There is no list of employees to check.",
                                        "Lambda Square Apartments",
                                        MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
  19. Return to the Payment Editor and click the Registration # text box
  20. In the Events section of the Properties window, double-click Leave
  21. Implement the event as follows:
    private void txtRegistrationNumber_Leave(object sender, EventArgs e)
    {
        string strUnitCode = "";
        bool registrationFound = false;
        XmlDocument xdApartments = new XmlDocument();
        XmlDocument xdRegistrations = new XmlDocument();
        string strFileName = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Apartments.xml";
        string strRegistrationsFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\TenantsRegistrations.xml";
    
        if (File.Exists(strRegistrationsFile))
        {
            xdRegistrations.Load(strRegistrationsFile);
            XmlElement xeRegistration = xdRegistrations.DocumentElement;
            XmlNodeList xnlRegistrations = xeRegistration.ChildNodes;
    
            foreach(XmlNode xnRegistration in xnlRegistrations)
            {
                if (xnRegistration.FirstChild.InnerText == txtRegistrationNumber.Text)
                {
                    registrationFound = true;
                    txtDateRegistered.Text = xnRegistration.FirstChild.NextSibling.NextSibling.InnerText;
                    txtRentStartDate.Text  = xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.InnerText;
                    txtTenantInformation.Text = xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + ": " +
                                                xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + " " +
                                                xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + ", " +
                                                xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + ", " +
                                                xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + " child(ren)";
                    strUnitCode = xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText;
                }
            }
    
            xdApartments.Load(strFileName);
            XmlElement xeApartment = xdApartments.DocumentElement;
            XmlNodeList xnlApartments = xeApartment.ChildNodes;
    
            foreach (XmlNode xnApartment in xnlApartments)
            {
                if (xnApartment.FirstChild.InnerText == strUnitCode)
                    txtApartmentInformation.Text = "Apart #:\t\t" + xnApartment.FirstChild.NextSibling.InnerText + ", " + Environment.NewLine +
                                                   "Bedroom(s):\t" + xnApartment.FirstChild.NextSibling.NextSibling.InnerText + Environment.NewLine +
                                                   "Bathroom(s):\t" + xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.InnerText + Environment.NewLine +
                                                   "Monthly Rate:\t" + xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + "/month" + Environment.NewLine +
                                                   "Deposit:\t" + xnApartment.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText;
            }
    
            if (registrationFound == false)
            {
                MessageBox.Show("There is no rental contral with that number.",
                                "Lambda Square Apartments",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtDateRegistered.Text = "";
                txtRentStartDate.Text = "";
                txtTenantInformation.Text = "";
            }
        }
        else
            MessageBox.Show("There is no list of rental contracts to check.",
                            "Lambda Square Apartments",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);       
    }
  22. Display the Payments form and double-click an unoccupied area of its body
  23. Change the document as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    
    namespace LambdaSquareApartments2
    {
        public partial class Payments : Form
        {
            public Payments()
            {
                InitializeComponent();
            }
    
            void ShowRentPayments()
            {
                XmlDocument xdPayments = new XmlDocument();
                XmlDocument xdEmployees = new XmlDocument();
                XmlDocument xdRegistrations = new XmlDocument();
                string strPaymentsFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Payments.xml";
                string strEmployeesFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Employees.xml";
                string strTenantsRegistrationsFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\TenantsRegistrations.xml";
    
                if (File.Exists(strPaymentsFile))
                {
                    xdPayments.Load(strPaymentsFile);
                    xdEmployees.Load(strEmployeesFile);
                    xdRegistrations.Load(strTenantsRegistrationsFile);
                    XmlElement xePayment = xdPayments.DocumentElement,
                               xeEmployee = xdEmployees.DocumentElement,
                               xeRegistration = xdRegistrations.DocumentElement;
                    XmlNodeList xnlPayments = xePayment.ChildNodes,
                                xnlEmployees = xeEmployee.ChildNodes,
                                xnlRegistrations = xeRegistration.ChildNodes;
    
                    lvwPayments.Items.Clear();
    
                    foreach (XmlNode xnPayment in xnlPayments)
                    {
                        ListViewItem lviPayment = new ListViewItem(xnPayment.FirstChild.InnerText); // Receipt Number
    
                        lviPayment.SubItems.Add(DateTime.Parse(xnPayment.FirstChild.NextSibling.InnerText).ToShortDateString()); // Payment Date
    
                        foreach (XmlNode xnEmployee in xnlEmployees)
                        {
                            if (xnEmployee.FirstChild.InnerText == xnPayment.FirstChild.NextSibling.NextSibling.InnerText)
                            {
                                lviPayment.SubItems.Add(xnEmployee.FirstChild.InnerText + ": " + xnEmployee.FirstChild.NextSibling.InnerText + " " + xnEmployee.FirstChild.NextSibling.NextSibling.InnerText); // Employee Number
                                break;
                            }
                        }
    
                        foreach (XmlNode xnRegistration in xnlRegistrations)
                        {
                            if (xnRegistration.FirstChild.InnerText == xnPayment.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)
                            {
                                lviPayment.SubItems.Add(xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.InnerText + ": " +
                                                        xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + " " +
                                                        xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + ", " +
                                                        xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + ", " +
                                                        xnRegistration.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText + " child(ren)");
                                break;
                            }
                        }
    
                        lviPayment.SubItems.Add(xnPayment.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText);  // Payment Amount
                        lviPayment.SubItems.Add(xnPayment.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText); // Notes
                        lvwPayments.Items.Add(lviPayment);
                    }
                }
            }
    
            private void Payments_Load(object sender, EventArgs e)
            {
                ShowRentPayments();
            }
        }
    }
  24. Return to the Payments form and double-click the New Payment button
  25. Change the document as follows:
    private void btnNewPayment_Click(object sender, EventArgs e)
    {
        int iReceiptNumber = 100000;
        PaymentEditor editor = new PaymentEditor();
        XmlDocument xdPayments = new XmlDocument();
        string strPaymentsFile = @"C:\Microsoft Visual C# Application Design\Lambda Square Apartments\Payments.xml";
    
        if (File.Exists(strPaymentsFile))
        {
            xdPayments.Load(strPaymentsFile);
            XmlElement xePayment = xdPayments.DocumentElement;
            XmlNodeList xnlPayments = xePayment.ChildNodes;
    
            foreach (XmlNode xnPayment in xnlPayments)
                iReceiptNumber = int.Parse(xnPayment.FirstChild.InnerText);
        }
    
        editor.txtReceiptNumber.Text = (iReceiptNumber + 1).ToString();
        editor.ShowDialog();
    
        ShowRentPayments();
    }
  26. On the Standard toolbar, click the Save All button Save All

Previous Copyright © 2005-2020, FunctionX Next