An XML Node
Introduction to XML Nodes
Consider the following example of an XML file named Videos.xml:
An XML file appears as an upside-down tree: it has a root (in this case
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. Consider the following code:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
Console.WriteLine("{0}", elm.Value);
}
else
Console.WriteLine("The file {0} could not be located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
This would produce:
Press any key to continue . . .
Because the Videos node doesn't have its own value, its Value property returns an empty string.
Character Entities in an Element Value
Besides these obvious types of values, you may want to display special characters as values of elements. Consider the following example:
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
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
' ' C C j j ³ ³ Ú Ú
< < D D k k ´ ´ Û Û > > E E l l µ ´ Ü Ü
& & F F m m ¶ ¶ Ý Ý
" " G G n n · · Þ Þ
! ! H H o o ¸ ¸ ß ß
" " I I p p ¹ ¹ à á
# # J J q q º º á à
$ $ K K r r » » â â
% % L L s s ¼ ¼ ã ã
& & M M t t ½ ½ ä ä
' ' N N u u ¾ ¾ å å
( ( O O v v ¿ ¿ æ æ
) ) P P w w À À ç ç
* * Q Q x x Á Á è è
+ + R R y y   é é
, , S S z z à à ê ê
- - T T { { Ä Ä ë ë
. . U U } } Å Å ì ì
/ / V V ~ ~ Æ Æ í í
0 0 W W empty Ç Ç î î
1 1 X X ¡ ¡ È È ï ï
2 2 Y Y ¢ ¢ É É ð ð
3 3 Z Z £ £ Ê Ê ñ ñ
4 4 [ [ ¤ ¤ Ë Ë ò ò
5 5 \ \ ¥ ¥ Ì Ì ó ó
6 6 ] ] ¦ ¦ Í Í ô ô
7 7 ^ ^ § § Î Î õ õ
8 8 _ _ ¨ ¨ Ï Ï ö ö
9 9 ` ` © © Ð Ð ÷ ÷
: : a a ª ª Ñ Ñ ø ø
; ; b b « « Ò Ò ù ù
< < c c ¬ ¬ Ó Ó ú ú = = d d Ô Ô û û > > e e ® ® Õ Õ ü ü
? ? f f ¯ ¯ Ö Ö ý ý
@ @ g g ° ° × × þ þ
A A h h ± ± Ø Ø ÿ ÿ
B B i i ² ² Ù Ù Ā A
There are still other codes to include special characters in an XML file.
Practical Learning: Introducing XML Elements
In the Solution Explorer, right-click CollegeParkAutoParts2 -> Add -> New Item...
In the Templates list, make sure XML File is selected.
Set the Name to models and click Add
To save the file, on the main menu, click File -> Save models.xml As...
Access the main folder of the current project and, inside of it, open a sub-folder of the same name (it should be selected already). In the sub-folder of the same name, open the bin sub-folder followed by the Release sub-folder. Click Save
Change the file as follows:
Access the Program.cs file and modify it as follows:
using System;
using System.IO;
using System.Xml;
namespace CollegeParkAutoParts2
{
class Program
{
static int Main(string[] args)
{
FileStream fsCPAP = null;
string strFilename = "models.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
fsCPAP = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
XmlTextReader rdrXml = new XmlTextReader(fsCPAP);
do
{
switch (rdrXml.NodeType)
{
case XmlNodeType.Text:
Console.WriteLine("Model: {0}",
rdrXml.Value);
break;
}
} while (rdrXml.Read());
}
else
Console.WriteLine("The {0} file was not found",
strFilename);
Console.WriteLine();
return 0;
}
}
}
Execute the application to see the result:
Model: NSX
Model: TL
Model: Spider
Model: A4
Model: RS6
Model: 323I
Model: M5
Model: Astro
Model: Cavalier
Model: Protégé
Press any key to continue . . .
Close the DOS window
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 and doesn't include their markups. Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
Console.WriteLine("{0}", elm.InnerText);
}
else
Console.WriteLine("The file {0} could not be located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
This would produce:
The Distinguished GentlemanJonathan Lynn112 MinutesDVDRHer AlibiBruce Beresford9
4 MinsDVDPG-13Chalte ChalteAziz Mirza145 MinsDVDN/R
Press any key to continue . . .
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.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
Console.WriteLine("{0}", elm.OuterXml);
}
else
Console.WriteLine("The file {0} could not be located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
This would produce:
Press any key to continue . . .
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};
Here is an example:
Console.WriteLine("{0}", elm.InnerXml);
This would produce:
Press any key to continue . . .
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.
A Collection of Child Nodes
To support the child nodes of a particular node, the XmlNode class is equipped with the ChildNodes property. 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:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
Console.WriteLine("The root element contains {0} nodes",
lstVideos.Count);
}
else
Console.WriteLine("The file {0} could not be located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
This would produce:
The root element contains 3 nodes
Press any key to continue . . .
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:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
Console.WriteLine(lstVideos[2]);;
}
else
Console.WriteLine("The file {0} could not be located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
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:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
for (int i = 0; i < lstVideos.Count; i++) Console.WriteLine("{0}",lstVideos[i].InnerText ); } else Console.WriteLine("The file {0} could not be located", strFilename); Console.WriteLine(); return 0; } } } This would produce: The Distinguished GentlemanJonathan Lynn112 MinutesDVDR Her AlibiBruce Beresford94 MinsDVDPG-13 Chalte ChalteAziz Mirza145 MinsDVDN/R Press any key to continue . . . 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: using System; using System.IO; using System.Xml; namespace VideoCollection { class Program { static int Main(string[] args) { string strFilename = "Videos.xml"; XmlDocument xmlDoc = new XmlDocument(); if (File.Exists(strFilename)) { xmlDoc.Load(strFilename); XmlElement elm = xmlDoc.DocumentElement; XmlNodeList lstVideos = elm.ChildNodes; foreach(XmlNode node in lstVideos) Console.WriteLine("{0}", node); } else Console.WriteLine("The file {0} could not be located", strFilename); Console.WriteLine(); return 0; } } } This would produce: System.Xml.XmlElement System.Xml.XmlElement System.Xml.XmlElement Press any key to continue . . . To better manage and manipulate the nodes of a collection of nodes, you must be able to access the desired node. The XmlNode combined with the XmlNodeList classes 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:
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
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.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
for (int i = 0; i < lstVideos.Count; i++) Console.WriteLine("{0}", lstVideos[i].FirstChild.InnerText ); } else Console.WriteLine("The file {0} could not be located", strFilename); Console.WriteLine(); return 0; } } } This would produce: The Distinguished Gentleman Her Alibi Chalte Chalte Press any key to continue . . . 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: using System; using System.IO; using System.Xml; namespace VideoCollection { class Program { static int Main(string[] args) { string strFilename = "Videos.xml"; XmlDocument xmlDoc = new XmlDocument(); if (File.Exists(strFilename)) { xmlDoc.Load(strFilename); XmlNode node = xmlDoc.DocumentElement.FirstChild; XmlNodeList lstVideos = node.ChildNodes; for (int i = 0; i < lstVideos.Count; i++) Console.WriteLine("{0}", lstVideos[i].InnerText ); } else Console.WriteLine("The file {0} could not be located", strFilename); Console.WriteLine(); return 0; } } } This would produce: The Distinguished Gentleman Jonathan Lynn 112 Minutes DVD R Press any key to continue . . . Consider the following modification of the Videos.xml file:
Remember that when using a for or a foreach loop 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:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
// Locate the root node and
// get a reference to its first child
XmlNode node = xmlDoc.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++)
Console.WriteLine("{0}",
lstActors[j].InnerText);
}
}
}
else
Console.WriteLine("The file {0} could not be located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
This would produce:
Eddie Murphy
Lane Smith
Sheryl Lee Ralph
Joe Don Baker
Victoria Rowell
Press any key to continue . . .
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:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
// Locate the root node and
// get a reference to its first child
XmlNode node = xmlDoc.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++)
Console.WriteLine("{0}",
lstActors[j].InnerText);
}
}
}
else
Console.WriteLine("The file {0} could not be located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
This would produce:
Eddie Murphy
Press any key to continue . . .
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};
No comments:
Post a Comment