Child Nodes

Introduction to XPath Keywords

An axis is a technique of locating a node or a series of nodes using a path. To address this issue, the XPath language provides some keywords that can be used in the expressions. As we are going to see, some keywords are optional and some other keywords are necessary or useful. If you decide to include one of those keywords in your XPath expression, you must use only a valid keyword. If you use a keyword that is not recognized, the compiler will throw an XPathException exception.

When used, an axis keyword is followed by ::, followed by the name of a node or an operator.

Consider the following XML document:

<?xml version="1.0" encoding="utf-8" ?>
<videos>
    <video>
        <title>The War of the Roses</title>
        <director>Danny DeVito</director>
        <cast-members>
            <actor>Michael Douglas</actor>
            <actor>Kathleen Turner</actor>
            <actor>Danny DeVito</actor>
        </cast-members>
    </video>
    <video>
        <title>Her Alibi</title>
        <director>Bruce Beresford</director>
        <length>94</length>
        <format>DVD</format>
        <rating>PG-13</rating>
    </video>
    <video>
        <title>Other People&#039;s Money</title>
        <director>Alan Brunstein</director>
        <year-released>1991</year-released>
        <cast-members>
            <actor>Danny DeVito</actor>
            <actor>Gregory Peck</actor>
            <actor>Penelope Ann Miller</actor>
        </cast-members>
        <cast-members>
            <actor>Dean Jones</actor>
            <actor>Piper Laurie</actor>
        </cast-members>
    </video>
    <video>
        <title>Duplex</title>
        <director>Danny DeVito</director>
        <cast-members>
            <narrator>Danny DeVito</narrator>
        </cast-members>
    </video>
</videos>

Practical LearningPractical Learning: Introducing XPath Axes

  1. Start Microsoft Visual Studio
  2. Create a Windows Forms App named XPathAxes

Accessing all Child Nodes

The child keyword is used to indicate that a child node must be accessed. The child keyword is followed by ::. If you want to see all child nodes, follow :: with *. Here is an example:

using System.Xml;

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

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

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("/videos/video/child::*")!;

            foreach (XmlNode xnVideo in xnlVideos)
            {
                lbxChildren.Items.Add(xnVideo.InnerXml);
            }
        }
    }
}

This would produce:

Accessing Child Nodes

Accessing some Child Nodes

The above code produces all nodes that are direct children of the video node. If a child node includes its own child nodes, the node and all its children would be considered as one. To get only specific child nodes, follow :: by the name of the child node to access. Here is an example that accesses the director child nodes:

using System.Xml;

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

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

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("/videos/video/child::director")!;

            foreach(XmlNode xnVideo in xnlVideos)
            {
                lbxDirectors.Items.Add(xnVideo.InnerText);
            }
        }
    }
}

This would produce:

Accessing Some Child Nodes

In the same way, you can access any child node by preceding it with the child keyword. In most cases, you can omit the child keyword. For example this:

XmlNodeList xnlVideos = xeVideo.SelectNodes(".//video/*/actor")!;

Is the same as:

using System.Xml;

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

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

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes(".//video/*/child::actor")!;

            foreach(XmlNode xnVideo in xnlVideos)
            {
                lbxDirectors.Items.Add(xnVideo.InnerText);
            }
        }
    }
}

This would produce:

Accessing Some Child Nodes

You can also apply any of the rules we have used so far. For example, the following code will produce the child nodes of the second video if the child node is named cast-members:

using System.Xml;

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

        private void btnVideos_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new XmlDocument();

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("/videos/video[3]/child::cast-members")!;

            foreach(XmlNode xnVideo in xnlVideos)
            {
                MessageBox.Show(xnVideo.OuterXml,
                                "Video Collection",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

This would produce:

Accessing Specific Nodes

Accessing Specific Nodes

Parent Nodes

Introduction

The parent keyword is used to get the parent of an element. Here is an example:

using System.Xml;

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

        private void btnVideos_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new XmlDocument();

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("//parent::director")!;

            foreach(XmlNode xnVideo in xnlVideos)
            {
                lbxDirectors.Items.Add(xnVideo.InnerText);
            }
        }
    }
}

This would produce:

Parent Nodes

The Ancestors of a Node

The ancestors of a node are its parent and grand-parent, up to the root of the XML file. To get the ancestors of a node, precede its name with the ancestor keyword. Here is an example:

using System.Xml;

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

        private void btnVideos_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new XmlDocument();

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("//ancestor::video")!;

            foreach(XmlNode xnVideo in xnlVideos)
            {
                MessageBox.Show(xnVideo.InnerXml,
                                "Video Collection",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

This would produce:

The Ancestors of a Node

The Ancestors of a Node

The Ancestors of a Node

The Ancestors of a Node

The Descendants of a Node

The descendants of a node are its child(ren) and grand-child(ren), down to the last grand-child of that node. To get the descendants of a node, precede its name with the descendant keyword. Here is an example:

using System.Xml;

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

        private void btnVideos_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new XmlDocument();

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("//descendant::cast-members")!;

            foreach (XmlNode xnVideo in xnlVideos)
            {
                MessageBox.Show(xnVideo.InnerXml,
                                "Video Collection",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

This would produce:

he Descendants of a Node

he Descendants of a Node

he Descendants of a Node

he Descendants of a Node

The Sibling that Precedes a Node

The previous sibling of a node is a node that comes before it in the tree while both nodes are on the same level. To get the collection of nodes that come before a certain node, precede its name with the preceding keyword. Here is an example:

using System.Xml;

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

        private void btnVideos_Click(object sender, EventArgs e)
        {
            XmlDocument xdVideos = new XmlDocument();

            xdVideos.Load("Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("//preceding::cast-members")!;

            foreach(XmlNode xnVideo in xnlVideos)
            {
                MessageBox.Show(xnVideo.OuterXml,
                                "Video Collection",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

This would produce:

Logical Disjunctions - Finding Either Value from a Common Node

Logical Disjunctions - Finding Either Value from a Common Node

The Previous Sibling of a Node

If your expression indludes the preceding keyword, the result would include the node itself and the next node of the same name in the same tree level. If you want to exclude the node itself from the result, in other words if you want to get only the next sibliing of the same level, use the preceding-sibling keyword.

The Sibling that Follows a Node

The following keyword is used to get the next node(s) that come after the referenced one but of the same tree level. Consider the following expression:

using System.Xml;

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

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

            xdVideos.Load("../../../Videos.xml");

            XmlElement xeVideo = xdVideos.DocumentElement!;
            XmlNodeList xnlVideos = xeVideo.SelectNodes("/videos/video/following::director")!;

            foreach (XmlNode xnVideo in xnlVideos)
            {
                lbxDirectors.Items.Add(xnVideo.InnerXml);
            }
        }
    }
}

This code would access the director nodes, excluding the first one:

The Sibling that Follows a Node

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2014-2024, FunctionX Thursday 27 June 2024, 11:40 Next