Nodes Axes
Nodes Axes
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'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 Learning: Introducing XPath Axes
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 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:
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:
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:
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:
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 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:
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:
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:
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2014-2024, FunctionX | Thursday 27 June 2024, 11:40 | Next |
|