Introduction

The XPath language provides many functions. Some functions are made to perform some of the operations we have applied already. Some other functions are meant to produce some results we have not gotten so far.

Practical LearningPractical Learning: Introducing XPath Functions

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

The Position of a Node

We have seen that we can use the square brackets to get to the position of a node. The XPath language has a function named position that can be used to access a node based on its position. To use it, in the square brackets of the node that is considered the parent, assign the desired position to position().

As you may know already, the first child of a node has an index of 1. Therefore, to get the first child node, assign 1 to the position() function. 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("/videos/video[position() = 1]")!;    

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

This would produce:

The Position of a Node

In the same way, to get to any node, assign its index to position().

The Last Child Node

To help you get to the last child node of a node, XPath proposes a function named last. Therefore, to get the last child node, pass last() as the index of the node that acts as the parent. 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!;
            // This expression first gets the 2nd video.
            // Then it gets the 3rd actor of that video
            XmlNodeList xnlVideos = xeVideo.SelectNodes("/videos/video[last()]")!;    

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

This would produce:

The Last Child Node

As an alternative, you can assign last() to position(). 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("/videos/video[position() = last()]")!;    

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

Consider the following 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("/videos/video/cast-members[last()]")!;    

            foreach(XmlNode xnVideo in xnlVideos)
            {
                MessageBox.Show(string.Format("Last cast-members section of any video " +
                                              "that has a cast-members section\n" +
                                              "____________________________________________________\n{0}",
                                              xnVideo.OuterXml),
                                              "Video Collection",
                                              MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

This would produce:

The Last Child Node

The Last Child Node

The Last Child Node

The Last Child Node

Notice that the result includes all nodes from a parent that has a cast-members section. If you want to get only the last node that has that section, include the whole path in parentheses excluding the square brackets and their index. 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("(/videos/video/cast-members)[last()]")!;    

            foreach(XmlNode xnVideo in xnlVideos)
            {
                MessageBox.Show(string.Format("Last cast-members section\n" +
                                              "____________________________________________________\n{0}",
                                              xnVideo.InnerXml),
                                              "Video Collection",
                                              MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

This would produce:

The Last Child Node

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2014-2024, FunctionX Tuesday 25 June 2024, 11:32 Next