Home

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. In our videos.xml example, 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.

Practical Learning Practical Learning: Using Child Nodes

  1. On the main menu, click File -> New -> File
  2. Select XML File and click Open
  3. Complete the file as follows:
     
    <?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>
    	<Property>
    		<PropertyCode>402-364</PropertyCode>
    		<PropertyType>Single Family</PropertyType>
    		<Bedrooms>3</Bedrooms>
    		<Bathrooms>2.5</Bathrooms>
    		<MonthlyRent>1750</MonthlyRent>
    		<Status>Occupied</Status>
    	</Property>
    	<Property>
    		<PropertyCode>725-784</PropertyCode>
    		<PropertyType>Townhouse</PropertyType>
    		<Bedrooms>4</Bedrooms>
    		<Bathrooms>2.5</Bathrooms>
    		<MonthlyRent>1920.50</MonthlyRent>
    		<Status>Available</Status>
    	</Property>
    	<Property>
    		<PropertyCode>836-903</PropertyCode>
    		<PropertyType>Townhouse</PropertyType>
    		<Bedrooms>4</Bedrooms>
    		<Bathrooms>2.5</Bathrooms>
    		<MonthlyRent>2140.50</MonthlyRent>
    		<Status>Needs Repair</Status>
    		</Property>
    	<Property>
    		<PropertyCode>284-247</PropertyCode>
    		<PropertyType>Single Family</PropertyType>
    		<Bedrooms>5</Bedrooms>
    		<Bathrooms>3.5</Bathrooms>
    		<MonthlyRent>2250.85</MonthlyRent>
    		<Status>Occupied</Status>
    	</Property>
    	<Property>
    		<PropertyCode>509-485</PropertyCode>
    		<PropertyType>Apartment</PropertyType>
    		<Bedrooms>3</Bedrooms>
    		<Bathrooms>2</Bathrooms>
    		<MonthlyRent>1250.25</MonthlyRent>
    		<Status>Available</Status>
    	</Property>
    	<Property>
    		<PropertyCode>740-958</PropertyCode>
    		<PropertyType>Townhouse</PropertyType>
    		<Bedrooms>3</Bedrooms>
    		<Bathrooms>1.5</Bathrooms>
    		<MonthlyRent>1650.50</MonthlyRent>
    		<Status>Occupied</Status>
    	</Property>
    </Properties>
  4. To save it, on the main menu, click File -> Save XMLFile2.xml As...
  5. Select the bin\Debug folder of the current project
  6. Change the file name to properties and click Save

A Collection of Child Nodes

To support the child nodes of a particular node, the XmlNode class is equipped with a property named ChildNodes. To identify the collection of child nodes of a node, the .NET Framework provides the XmlNodeList class. Therefore, the ChildNodes property of an XmlNode object is of type XmlNodeList. This 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 btnDocument_Click(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string strFilename = "videos.xml";

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

        MessageBox.Show("The root element contains " +
                        lstVideos.Count + " nodes");
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found");
}

This would produce:

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

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 btnDocument_Click(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string strFilename = "videos.xml";

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

        MessageBox.Show(lstVideos[2].InnerText);
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found");
}

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 btnDocument_Click(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string strFilename = "videos.xml";

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

        for (int i = 0; i < lstVideos.Count; i++)
            MessageBox.Show(lstVideos[i].InnerText);
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found");
}

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 btnDocument_Click(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string strFilename = "videos.xml";

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

        foreach (XmlNode node in lstVideos)
            MessageBox.Show(node.InnerText);
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found");
}

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 doesn't 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:

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

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

        foreach (XmlNode node in lstVideos)
            lbxVideos.Items.Add(node.FirstChild.InnerText);
    }
    else
        MessageBox.Show("The file " + strFilename + " was not found");
}

This would produce:

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 btnDocument_Click(object sender, EventArgs e)
{
    XmlDocument docVideo = new XmlDocument();
    string strFilename = "videos.xml";

    if (File.Exists(strFilename))
    {
        docVideo.Load(strFilename);
        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 " + strFilename + " was not found");
}

This would produce:

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 btnDocument_Click(object sender, EventArgs e)
{
    string strFilename = "videos.xml";
    XmlDocument docVideo = new XmlDocument();

    if (File.Exists(strFilename))
    {
        docVideo.Load(strFilename);
        // 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 " + strFilename + " was not found");
}

This would produce:

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 btnDocument_Click(object sender, EventArgs e)
{
    string strFilename = "videos.xml";
    XmlDocument docVideo = new XmlDocument();

    if (File.Exists(strFilename))
    {
        docVideo.Load(strFilename);
        // 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 " + strFilename + " was not found");
}

This would produce:

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, Actors, 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};

Practical Learning Practical Learning: Using The Sibling of Child Nodes

  1. Access the Central.cs file and change it as follows:
     
    private void SolasPropertyRental_Load(object sender, EventArgs e)
    {
        string strFilename = "Properties.xml";
        XmlDocument docProperties = new XmlDocument();
    
        if (File.Exists(strFilename))
        {
            docProperties.Load(strFilename);
            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 " + strFilename + " file was not found");
    }
  2. Execute the application to see the result
     
    Solas Property Rental - Rental Properties
  3. Close the form and return to your programming environment
 

Previous Copyright © 2007 FunctionX, Inc. Next