Home

Introduction to XML Elements

 

Elements Fundamentals

 

Introduction

Consider the following file named videos.xml:

<?xml version="1.0" encoding="utf-8" ?>
<videos>
    <video>
    	<title>The Distinguished Gentleman</title>
    	<director>Jonathan Lynn</director>
    	<length>112 Minutes</length>
    	<format>DVD</format>
    	<rating>R</rating>
    </video>
    <video>
    	<title>Her Alibi</title>
    	<director>Bruce Beresford</director>
	<length>94 Minutes</length>
        <format>DVD</format>
        <rating>PG-13</rating>
    </video>
    <video>
        <title>Chalte Chalte</title>
	<director>Aziz Mirza</director>
	<length>145 Minutes</length>
	<format>DVD</format>
	<rating>N/R</rating>
    </video>
    <video>
        <title>Sneakers</title>
	<director>Phil Alden Robinson</director>
	<length>2 Hours 6 Minutes</length>
	<format>DVD</format>
	<rating>N/R</rating>
    </video>
</videos>

An element in an XML document is an object that begins with a start-tag, may contain a value, and may terminate with an end-tag. Based on this, the combination of a start-tag, the value, and the end-tag is called an element. An element can be more than that but for now, we will consider that an element is primarily characterized by a name and possibly a value.

You use XML elements through the IXMLNode class. To access an XML element, you can declare a variable of type IXMLNode.

Practical LearningPractical Learning: Introducing XML Elements

  1. Start C++Builder and create a VCL Forms Application
  2. To save it, on the Standard toolbar, click the Save All button
  3. Click the Create New Folder button and type SolasPropertyRental1
  4. Display the SolasPropertyRental1 folder in the Save In combo box
  5. Save the unit as Central.cpp
  6. Save the project as SolasPropertyRental
  7. In the Project Manager, double-click Rental.cpp to open it and click the Design button
  8. In the Object Inspector, change the name of the form to frmCentral and press Enter
  9. Design the form as follows:
     
    Properties Listing
    Control Text Name Other Properties
    TLabel Solas Property Rental   Font: Times New Roman, 21.75pt, style=Bold
    ForeColor: MediumBlue
    TLabel Properties Listing   Font: Times New Roman, 21.75pt, style=Bold
    ForeColor: Blue
    TListView   lvwProperties GridLines: true
    RowSelect: true
    ViewStyle: vsReport
    Columns
    Caption Alignment Width
    Prop #   65
    Property Type   85
    Bedrooms taRightJustify 65
    Bathrooms taRightJustify 65
    Monthly Rent taRightJustify 80
    Status   70
  10. Save all
  11. On the main menu, click File -> New -> Other...
  12. In the Items Category list, select Web Documents.
    In the right list, select XML File and click OK
  13. Change the file as follows:
     
    <?xml version="1.0" encoding="utf-8"?>
    <Properties>
        <Property>
        </Property>
    </Properties>
  14. On the main menu, click File -> Save
  15. Change the name to properties.xml
  16. Click Save

The Name of an Element

The name of an element is the string that represents the tag. For example, in <Director>, the word Director is the name of the element. An element must have at least a start-tag. All of the tags we have seen so far were created as elements. When creating your elements, remember to follow the rules we defined for names.

To support the name of a node, the IXMLNode class is equipped with a property named NodeName that can be used to identify an existing element. Here is an example of accessing it:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
    TXMLDocument *docVideos = new TXMLDocument(frmMain);
    docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

    IXMLNode *nodVideo = docVideos->DocumentElement;
    ShowMessage(nodVideo->NodeName);
}
//---------------------------------------------------------------------------

This would produce:

Videos

 

Practical LearningPractical Learning: Setting the Names of Elements

  1. Change the properties.xml file as follows:
     
    <?xml version="1.0" encoding="utf-8"?>
    <Properties>
        <Property>
    	<PropertyCode></PropertyCode>
    	<PropertyType></PropertyType>
    	<Bedrooms></Bedrooms>
    	<Bathrooms></Bathrooms>
    	<MonthlyRent></MonthlyRent>
    	<Status></Status>
        </Property>
    </Properties>
  2. Save the file

The Text or Value of an Element

The value of an element is the item displayed on the right side of the start-tag. It is also called the text of the element. In the case of <director>Jonathan Lynn</director>, the "Jonathan Lynn" string is the value of the director element. To support the text or value of an element, the IXMLNode interface is equipped with a property named Text:

__property DOMString Text;

While the value of one element can be a number, the value of another element can be a date. Yet another element can use a regular string as its value. Consider the following example:

<?xml version="1.0" encoding="utf-8" ?>
<videos>
    <video>
    	<title>The Distinguished Gentleman</title>
    	<director>Jonathan Lynn</director>
    	<lengthinminutes>112</lengthinminutes>
        <rating>R</rating>
    	<price>14.95</price>
    </video>
    <video>
    	<title>Her Alibi</title>
    	<director>Bruce Beresford</director>
	<lengthinminutes>94</lengthinminutes>
        <rating>PG-13</rating>
    	<price>8.75</price>
    </video>
    <video>
        <title>Chalte Chalte</title>
	<director>Aziz Mirza</director>
	<lengthinminutes>145</lengthinminutes>
	<rating>N/R</rating>
    	<price>29.95</price>
    </video>
    <video>
        <title>Sneakers</title>
	<director>Phil Alden Robinson</director>
	<lengthinminutes>126</lengthinminutes>
	<rating>N/R</rating>
    	<price>14.95</price>
    </video>
</videos>

Notice that the price elements contain numbers that look like currency values and the lengthinminutes elements use an integer as value.

To get the value of an element, you can access its Text property. Obviously not all elements have a value. For example, in the above example, the videos element does not have a value. If you try accessing the value of an element when that element does not have one, the compiler would throw an EXMLDocError exception:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	// Locate the root node
	IXMLNode *nodRoot = docVideos->DocumentElement;

	ShowMessage(nodRoot->Text);
}
//---------------------------------------------------------------------------

Exception

To assist you with checking whether an element has a value, the IXMLNode interface is equipped with a Boolean property named IsTextElement:

__property Boolean IsTextElement;

If the element that accesses this property has a value, it returns true. Otherwise it produces false. Here is an example of checking whether an element (the root in this case) has a value

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	// Locate the root node
	IXMLNode *nodRoot = docVideos->DocumentElement;

	if( nodRoot->IsTextElement == True )
		ShowMessage(nodRoot->Text);
	else
		ShowMessage("That element ain't got no a value");
}
//---------------------------------------------------------------------------

This would produce:

Has Value

Practical LearningPractical Learning: Setting the Values of Elements

  1. Change the properties.xml 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>
    </Properties>
  2. Save the file

Empty Elements

An element may not have a value but only a name. Consider the following example:

<?xml version="1.0" encoding="utf-8"?>
<videos>
  <video>
    <title>The Distinguished Gentleman</title>
    <director>Jonathan Lynn</director>
  </video>
</videos>

In this case, the video element does not have a value. It is called an empty element. When a tag is empty, the Text property of its IXMLNode object would return an empty value.

Now consider the following example:

<?xml version="1.0" encoding="utf-8"?>
<videos>
  <video>
    <title>The Distinguished Gentleman</title>
    <director>Jonathan Lynn</director>
  </video>
  <video>The Day After Tomorrow
    <director>Jonathan Lynn</director>
    <length>123 Minutes</length>
  </video>
</videos>

This time, the first video node has no. The second video has a value, which is The Day After Tomorrow. That means the Text property of the first video node has an empty value and the Text value of the second video node is The Day After Tomorrow.

Character Entities in an Element Value

Besides the obvious types of values, you may want to display special characters as values of elements. Consider the following example:

<?xml version="1.0" encoding="utf-8" ?>
<Employees>
    <Employee>
	<FullName>Sylvie <Bellie> Aronson</FullName>
	<Salary>25.64</Salary>
	<DepartmentID>1</DepartmentID>
    </Employee>
    <Employee>
	<FullName>Bertrand Yamaguchi</FullName>
	<Salary>16.38</Salary>
	<DepartmentID>4</DepartmentID>
    </Employee>
</Employees>

If you try using this XML document, for example, if you try displaying it in a browser, you would receive an error:

Preview

The reason is that when the parser reaches the <FullName>Sylvie <Bellie> Aronson</FullName> line, it thinks that <Bellie> is a tag but then <Bellie> is not closed. The parser concludes that the document is not well-formed, that there is an error. For this reason, to display a special symbol as part of a value, you can use its character code. For example, the < (less than) character is represented with &lt and the > (greater than) symbol can be used with &gt;. Therefore, the above code can be corrected as follows:

<?xml version="1.0" encoding="utf-8" ?>
<Employees>
	<Employee>
		<FullName>Sylvie &lt;Bellie&gt; Aronson</FullName>
		<Salary>25.64</Salary>
		<DepartmentID>1</DepartmentID>
	</Employee>
	<Employee>
		<FullName>Bertrand Yamaguchi</FullName>
		<Salary>16.38</Salary>
		<DepartmentID>4</DepartmentID>
	</Employee>
</Employees>

This would produce:

Preview

Here is a list of other codes you can use for special characters:

Code Symbol Code Symbol Code Symbol Code Symbol Code Symbol
&apos; ' &#067; C &#106; j &#179; ³ &#218; Ú
&lt; < &#068; D &#107; k &#180; ´ &#219; Û
&gt; > &#069; E &#108; l &#181; ´ &#220; Ü
&amp; & &#070; F &#109; m &#182; &#221; Ý
&quot; " &#071; G &#110; n &#183; · &#222; Þ
&#033; ! &#072; H &#111; o &#184; ¸ &#223; ß
&#034; " &#073; I &#112; p &#185; ¹ &#224; á
&#035; # &#074; J &#113; q &#186; º &#225; à
&#036; $ &#075; K &#114; r &#187; » &#226; â
&#037; % &#076; L &#115; s &#188; ¼ &#227; ã
&#038; & &#077; M &#116; t &#189; ½ &#228; ä
&#039; ' &#078; N &#117; u &#190; ¾ &#229; å
&#040; ( &#079; O &#118; v &#191; ¿ &#230; æ
&#041; ) &#080; P &#119; w &#192; À &#231; ç
&#042; * &#081; Q &#120; x &#193; Á &#232; è
&#043; + &#082; R &#121; y &#194; Â &#233; é
&#044; , &#083; S &#122; z &#195; Ã &#234; ê
&#045; - &#084; T &#123; { &#196; Ä &#235; ë
&#046; . &#085; U &#125; } &#197; Å &#236; ì
&#047; / &#086; V &#126; ~ &#198; Æ &#237; í
&#048; 0 &#087; W &#160; empty &#199; Ç &#238; î
&#049; 1 &#088; X &#161; ¡ &#200; È &#239; ï
&#050; 2 &#089; Y &#162; ¢ &#201; É &#240; ð
&#051; 3 &#090; Z &#163; £ &#202; Ê &#241; ñ
&#052; 4 &#091; [ &#164; ¤ &#203; Ë &#242; ò
&#053; 5 &#092; \ &#165; ¥ &#204; Ì &#243; ó
&#054; 6 &#093; ] &#166; ¦ &#205; Í &#244; ô
&#055; 7 &#094; ^ &#167; § &#206; Î &#245; õ
&#056; 8 &#095; _ &#168; ¨ &#207; Ï &#246; ö
&#057; 9 &#096; ` &#169; © &#208; Ð &#247; ÷
&#058; : &#097; a &#170; ª &#209; Ñ &#248; ø
&#059; ; &#098; b &#171; « &#210; Ò &#249; ù
&#060; < &#099; c &#172; ¬ &#211; Ó &#250; ú
&#061; = &#100; d &#173; ­ &#212; Ô &#251; û
&#062; > &#101; e &#174; ® &#213; Õ &#252; ü
&#063; ? &#102; f &#175; ¯ &#214; Ö &#253; ý
&#064; @ &#103; g &#176; ° &#215; × &#254; þ
&#065; A &#104; h &#177; ± &#216; Ø &#255; ÿ
&#066; B &#105; i &#178; ² &#217; Ù &#256; A

There are still other codes to include special characters in an XML file.

The XML Code of an Element

As mentioned so far, a typical XML node has a start tag, may have a value and may have child nodes. To give you access to the tags and values of the children of a node, the IXMLNode interface is equipped with a string property named XML:

__property DOMString XML;

Here is an example of accessing it:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;

	ShowMessage(nodVideo->XML);
}
//---------------------------------------------------------------------------

Node Text

You can also access it from its read-implement, a method named GetXML and whose syntax is:

DOMString GetXML();

This method returns a string that includes the symbols, the name(s), and the value(s) if any, of the node that called it.

Practical LearningPractical Learning: Creating Elements

  1. Completer the properties.xml 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>
  2. Save the file

The  Child Nodes of  a Node

 

Introduction

Consider the following file named videos.xml:

<?xml version="1.0" encoding="utf-8" ?>
<videos>
    <video>
    	<title>The Distinguished Gentleman</title>
    	<director>Jonathan Lynn</director>
    	<length>112 Minutes</length>
    	<format>DVD</format>
    	<rating>R</rating>
    </video>
    <video>
    	<title>Her Alibi</title>
    	<director>Bruce Beresford</director>
	<length>94 Minutes</length>
        <format>DVD</format>
        <rating>PG-13</rating>
    </video>
</videos>

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 the above XML code 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: Introducing Child Nodes

  1. Display the frmCentral form
  2. In the Internet section of the Tool Palette, click TXMLDocument and click the form
  3. In the Object Inspector, change the Name to xmlProperties
  4. Click the FileName field and click its ellipsis button
  5. Locate and select the properties.xml file
  6. Still in the Object Inspector, set the Active to true
  7. Save all

A Collection of Child Nodes

To support the child nodes of a particular node, the IXMLNode interface is equipped with a property named ChildNodes. To identify the collection of child nodes of a node, the VCL provides the TXMLNodeList class. The TXMLNodeList class starts as follows:

class TXMLNodeList : public TInterfacedObject,
		     public IXMLNodeList;

As you can see, the TXMLNodeList class implements an interface named IXMLNodeList. The ChildNodes property of an IXMLNode collection is of type IXMLNodeList. This property is declared as follows:

__property IXMLNodeList ChildNodes;

When this property is used, it produces an IXMLNodeList list, which is a collection of all nodes that share the same parent. Each item in the collection is of type IXMLNode.

Practical Learning Practical Learning: Creating a Collection of Child Nodes

  1. On the frmCentral form, double-click an unoccupied area of its body to launch the Create event
  2. Write code as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TfrmCentral::FormCreate(TObject *Sender)
    {
    	IXMLNode *nodRoot = this->xmlProperties->DocumentElement;
    
    	IXMLNodeList *ListOfProperties = nodRoot->ChildNodes;
    }
    //---------------------------------------------------------------------------
  3. Save all

The Value of a Node

Consider the following document:

<?xml version="1.0" encoding="utf-8"?>
<videos>
  <video>
    <title>The Distinguished Gentleman</title>
    <director>Jonathan Lynn</director>
  </video>
  <video>The Day After Tomorrow
    <director>Jonathan Lynn</director>
    <length>123 Minutes</length>
  </video>
  <video></video>
  <video>The General&apos;s Daughter
    <rating>PG-13</rating>
    <color></color>
    <yearreleased>1999</yearreleased>
  </video>
</videos>

As seen previously, the video node has children, and as mentioned already, one node can have a value while another would not. In the same, when having nodes of the same level, such as the video nodes in this example, the second and third video nodes have a value. Although these parent nodes do not have the same children, the children, if any, of each are allowed to have or not have values. These are pieces of information you should know before starting to perform operations on nodes as we will study in the next lesson.

The Number of Child Nodes of a Node

To give you the number of child nodes that an element contains, the TXMLNodeList class is equipped with a property named Count:

__property int Count;

Here is an example of using it:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;

	IXMLNodeList *lstVideos = nodVideo->ChildNodes;

	ShowMessage("The root element contains " +
		    AnsiString(lstVideos->Count) + " nodes");

}
//---------------------------------------------------------------------------

This would produce:

Videos

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

Practical Learning Practical Learning: Getting the Number of Child Nodes

  1. Change the code as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TfrmCentral::FormCreate(TObject *Sender)
    {
        IXMLNode *nodRoot = this->xmlProperties->DocumentElement;
    
        IXMLNodeList *ListOfProperties = nodRoot->ChildNodes;
    
        ShowMessage("We currently have " +
    	AnsiString(ListOfProperties->Count) + " properties to rent.");
    }
    //---------------------------------------------------------------------------
  2. Press F9 to execute
     
    Solas Property Rental
  3. Close the form and return to your programming environment

Accessing a Node in a Collection

The children of a node, that is, the members of a ChildNodes property, or the members of an IXMLNodeList 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 IXMLNodeList interface is equipped with the overloaded [] property. For example, if a node has four children, to access the third, you can apply an index of 2 to the [] property. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;

	IXMLNodeList *lstVideos = nodVideo->ChildNodes;

	lstVideos[2];
}
//---------------------------------------------------------------------------

When applying the square brackets operator to access a node based on its index, the operation produces an IXMLNode object that has all the characteristics of a node as we have see so far. This means that an IXMLNode[index] item is an XML element that has a name, may have a value, and may have children. To access a child node, you can apply the [] operator to it. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;

	IXMLNodeList *lstVideos = nodVideo->ChildNodes;

	ShowMessage((lstVideos[0])[0]->XML);
}
//---------------------------------------------------------------------------

Fortunately, the compiler can access the collection of elements of a node so you do not need the parentheses. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;

	IXMLNodeList *lstVideos = nodVideo->ChildNodes;

	ShowMessage((lstVideos[0])[0]->XML);
	ShowMessage(lstVideos[0][1]->XML);
}
//---------------------------------------------------------------------------

As an alternative, to give you access to a child of a node, the IXMLNode interface is equipped with a method named Get. Its syntax is:

IXMLNode Get(int Index);

This method takes an integer as argument. That integer is the index of the element you want to access. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;
	IXMLNodeList *lstVideos = nodVideo->ChildNodes;

	ShowMessage((lstVideos[0])[0]->XML);
	ShowMessage(lstVideos[0][1]->XML);
	ShowMessage(lstVideos[0].Get(2)->XML);
}
//---------------------------------------------------------------------------

Notice that you have various options to access a child of a node. You can use any of these techniques to access the children of a node, the grandchildren of a node, and so on. Here are examples:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);
	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	// Locate the root node
	IXMLNode *nodRoot = docVideos->DocumentElement;
	IXMLNodeList *lstVideos = nodRoot->ChildNodes;

	ShowMessage(lstVideos[0].Get(0)->XML);
	ShowMessage(lstVideos[0].Get(1)->XML);
	ShowMessage(lstVideos[0].Get(2)->XML);
	ShowMessage(lstVideos[0].Get(3)->XML);
	ShowMessage(lstVideos[0].Get(3)->ChildNodes->Get(0)->Text);
	ShowMessage(lstVideos[0].Get(3)->ChildNodes->Get(1)->Text);
	ShowMessage(lstVideos[0].Get(3)->ChildNodes->Get(2)->Text);
	ShowMessage(lstVideos[0].Get(3)->ChildNodes->Get(3)->Text);
	ShowMessage(lstVideos[0].Get(3)->ChildNodes->Get(4)->Text);
}
//---------------------------------------------------------------------------

Practical Learning Practical Learning: Accessing the Child Nodes of a Node

  1. Change the code as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TfrmCentral::FormCreate(TObject *Sender)
    {
        // Get a reference to the root node
        IXMLNode *nodRoot = this->xmlProperties->DocumentElement;
        // Get a list of the child nodes of the root
        IXMLNodeList *Properties = nodRoot->ChildNodes;
    
        // Get each item of the list
        for(int i = 0; i < Properties->Count; i++)
        {
    	// Add each item to the list view
    	TListItem *lviProperty = lvwProperties->Items->Add();
    
    lviProperty->Caption = Properties[0].Get(i)->ChildNodes->Get(0)->Text;
    lviProperty->SubItems->Add(Properties[0].Get(i)->ChildNodes->Get(1)->Text);
    lviProperty->SubItems->Add(Properties[0].Get(i)->ChildNodes->Get(2)->Text);
    lviProperty->SubItems->Add(Properties[0].Get(i)->ChildNodes->Get(3)->Text);
    lviProperty->SubItems->Add(Properties[0].Get(i)->ChildNodes->Get(4)->Text);
    lviProperty->SubItems->Add(Properties[0].Get(i)->ChildNodes->Get(5)->Text);
        }
    }
    //---------------------------------------------------------------------------
  2. Press F9 to execute
     
    Solas Property Rental
  3. Close the form and return to your programming environment

The Parent of a Node

Not all nodes have children, obviously. To find out whether a node has children, check its HasChildNodes Boolean property that is declared as follows:

__property Boolean HasChildNodes;

If a node is a child, to get its parent, you can access its ParentNode property. It is declared as:

__property IXMLNode ParentNode;

Notice that the ParentNode property is an element of type IXMLNode. Here is an example of accessing it:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;

	IXMLNodeList *lstVideos = nodVideo->ChildNodes;

	ShowMessage((lstVideos[0])[0]->XML);
	ShowMessage(lstVideos[0][1]->XML);
	ShowMessage(lstVideos[0].Get(2)->XML);
	ShowMessage(lstVideos[0].Get(3)->ParentNode->XML);
}
//---------------------------------------------------------------------------

You can also access the parent of a node by calling the IXMLNode::GetParentNode() method. Its syntax is:

IXMLNode GetParentNode();

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>.

To give you access to the first child of a node, the TXMLNodeList class is equipped with a method named First whose syntax is:

IXMLNode First();

Here is an example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	IXMLNode *nodVideo = docVideos->DocumentElement;

	IXMLNodeList *lstVideos = nodVideo->ChildNodes;

	ShowMessage(lstVideos[0].First()->XML);
}
//---------------------------------------------------------------------------

This would produce:

Root Node

In the same way, you can scan the document so that, when you get to a node, you can access its first child, if it has any. Here are examples:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
    TXMLDocument *docVideos = new TXMLDocument(frmMain);

    docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

    IXMLNode *nodVideo = docVideos->DocumentElement;

    IXMLNodeList *lstVideos = nodVideo->ChildNodes;

    for(int i = 0; i < lstVideos->Count; i++)
	lbxTitles->Items->Add(lstVideos[0].Get(i)->ChildNodes->First()->Text);
}
//---------------------------------------------------------------------------

This would produce:

Videos

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 give you access to the last child of a node, the IXMLNodeList interface is equipped with a method named Last and whose syntax is:

IXMLNode Last();

Here is an example of calling it:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
    TXMLDocument *docVideos = new TXMLDocument(frmMain);

    docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

    IXMLNode *nodVideo = docVideos->DocumentElement;

    IXMLNodeList *lstVideos = nodVideo->ChildNodes;

    ShowMessage(lstVideos[0].Last()->XML);
}
//---------------------------------------------------------------------------

Videos

In the same way, you can first access a child node, then access the last one of its children. When calling the IXMLNodeList::Last() method, if the node that calls it does not have any children, the compiler would throw an EAccessViolation exception.

The Siblings of a Node

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>
    <video>
        <title>Sneakers</title>
	<director>Phil Alden Robinson</director>
	<length>2 Hrs 6 Mins</length>
	<format>DVD</format>
	<rating>N/R</rating>
    </video>
</videos>

The child nodes that are nested in a parent node and share the same level are referred to as siblings. In our videos.xml 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, castmembers, and length are siblings. Obviously, to get a sibling, you must first have a node.

Consider the following example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	// Locate the root node
	IXMLNode *nodRoot = docVideos->DocumentElement;
	IXMLNodeList *lstVideos = nodRoot->ChildNodes;

	ShowMessage(lstVideos[0].Get(0)[0].ChildNodes->First()->XML );

}
//---------------------------------------------------------------------------

This code accesses the first child node of the first element:

Videos

To give you access to the next sibling of a node, the IXMLNode interface is equipped with a method named NextSibling. Its syntax is:

IXMLNode NextSibling();

Therefore, to call the IXMLNode::NextSibling() method, first get to, or access, a node. Then call this method to get to the most next sibling under it. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
    TXMLDocument *docVideos = new TXMLDocument(frmMain);

    docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

    // Locate the root node
    IXMLNode *nodRoot = docVideos->DocumentElement;
    IXMLNodeList *lstVideos = nodRoot->ChildNodes;

    ShowMessage(lstVideos[0].Get(0)[0].ChildNodes->First()->NextSibling()->XML);
}
//---------------------------------------------------------------------------

This would produce:

Videos

In the same way, you can access an element, then access its next sibling, then access the next sibling of that other one, and so on. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnDocumentClick(TObject *Sender)
{
	TXMLDocument *docVideos = new TXMLDocument(frmMain);

	docVideos->LoadFromFile(L"C:\\Programs\\videos.xml");

	// Locate the root node
	IXMLNode *nodRoot = docVideos->DocumentElement;
	IXMLNodeList *lstVideos = nodRoot->ChildNodes;

	ShowMessage(lstVideos[0].Get(0)[0].ChildNodes->First()->NextSibling()->NextSibling()->XML );
}
//---------------------------------------------------------------------------

Previous Copyright © 2008-2009 FunctionX, Inc. Next