Home

Operations on XML Elements

 

Adding a Simple Element

To programmatically create a new element, you can declare an XmlElement variable. To add the new element to the file, the XmlDocument class provides the CreateElement() method that is overloaded with three versions. One of the versions uses the following syntax:

Overloads Public Function CreateElement(ByVal name As String) As XmlElement

Using this method, to create a new element, call it and pass it the name of the new element. If you want the element to have a value, the XmlDocument class is equipped with the CreateTextNode() method. This method returns an XmlText value. The syntax of this method is:

Public Overridable Function CreateTextNode(ByVal text As String) As XmlText

This method takes as argument the string that would constitute the value of the element. The calls to XmlDocument.CreateElement() and XmlDocument.CreateTextNode() allow you to initialize a new element. In order to actually add the new element, you must specify its position in the tree: whether it would be the first or the last node, whether you want to position it before or after a node of your choice. To support the positions of existing nodes, the XmlNode class, which is the ancestor of all XML nodes of the .NET Framework, provides various appropriate methods.

 One of these methods is AppendChild(), which is used to add an element as the last child of its parent. The syntax of the XmlNode.AppendChild() method is:

Public Overridable Function AppendChild(ByVal newChild As XmlNode) As XmlNode

Imagine you have a simple XML file that has only the root and one level of elements as follows:

<?xml version="1.0" encoding="utf-8"?>
<Holidays>
  <Holiday>New Year's Day</Holiday>
  <Holiday>Birthday of Martin Luther King, Jr.</Holiday>
  <Holiday>Washington's Birthday</Holiday>
</Holidays>

To add a new Holiday element to this file, based on the above discussions, you can use code as follows:

Private Sub AddHoliday()
        Dim docXML As XmlDocument = New XmlDocument
        docXML.Load("Holidays.xml")

        Dim elmXML As XmlElement = docXML.CreateElement("Holiday")
        Dim txtXML As XmlText = docXML.CreateTextNode("Memorial Day")
        docXML.DocumentElement.AppendChild(elmXML)
        docXML.DocumentElement.LastChild.AppendChild(txtXML)

        docXML.Save("Holidays.xml")
End Sub

Practical Learning Practical Learning: Adding Elements

  1. To give the user the ability to create a new car make and a new model, change the Exercise.vb file as follows:
     
    Imports System
    Imports System.xml
    
    Module Exercise
        
        Public Sub Main()
    
            Dim mnuChoice As Char = "q"
    
            Console.WriteLine()
            Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=")
            Console.WriteLine("=-= College Park Auto-Parts =-=")
            Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=")
    
            Do
                Console.WriteLine("=-= Main Menu =-=")
                Console.WriteLine("0 - Exit")
                Console.WriteLine("1 - Add New Car Make")
                Console.WriteLine("2 - Add New Car Model")
                Console.Write("Your Choice: ")
                mnuChoice = Char.Parse(Console.ReadLine())
    
                If mnuChoice = "1" Then
                    CreateNewMake()
                ElseIf mnuChoice = "2" Then
                    CreateNewModel()
                End If
    
         If (mnuChoice <> "0") And (mnuChoice <> "1") And (mnuChoice <> "2") Then
                    Console.WriteLine("Invalid Choice: Please try again")
                End If
            Loop While (mnuChoice <> "0")
    
            Console.WriteLine("Thank you!")
        End Sub
    
        Private Sub CreateNewMake()
            Dim strNewMake As String
    
            Console.Write("Enter Car Make: ")
            strNewMake = Console.ReadLine()
    
            ' Open the Makes.xml file
            Dim docXMLFile As XmlDocument = New XmlDocument
            docXMLFile.Load("Makes.xml")
    
            ' Get the root node so we can explore its children
            Dim nodRoot As XmlElement = docXMLFile.DocumentElement
            ' Store all the values of the elements in a string
            Dim allMyChildren As String = nodRoot.InnerText
            ' Locate the new make among the values of the elements
            Dim indexLookForNewMake As Integer = allMyChildren.IndexOf(strNewMake)
    
            ' If the car make exists already, don't add it
            If indexLookForNewMake >= 0 Then
                Exit Sub
            Else
                ' If the car is not in the list already, add it as a Make element
                Dim elmXML As XmlElement = docXMLFile.CreateElement("Make")
                ' Create its value using the string provided by the user
                Dim txtXML As XmlText = docXMLFile.CreateTextNode(strNewMake)
                ' Add the new element at the end of the file
                docXMLFile.DocumentElement.AppendChild(elmXML)
                ' Specify its text
                docXMLFile.DocumentElement.LastChild.AppendChild(txtXML)
    
                ' Save the file
                docXMLFile.Save("Makes.xml")
            End If
        End Sub
    
        Private Sub CreateNewModel()
            Dim strNewModel As String = Nothing
    
            Console.Write("Enter Car Model: ")
            strNewModel = Console.ReadLine()
    
            Dim docXMLFile As XmlDocument = New XmlDocument
            docXMLFile.Load("Models.xml")
    
            Dim nodRoot As XmlElement = docXMLFile.DocumentElement
            Dim allMyChildren As String = nodRoot.InnerText
            Dim indexNewModel As Integer = allMyChildren.IndexOf(strNewModel)
    
            If indexNewModel >= 0 Then
                Exit Sub
            Else
                Dim elmXML As XmlElement = docXMLFile.CreateElement("Model")
                Dim txtXML As XmlText = docXMLFile.CreateTextNode(strNewModel)
    
                docXMLFile.DocumentElement.AppendChild(elmXML)
                docXMLFile.DocumentElement.LastChild.AppendChild(txtXML)
    
                docXMLFile.Save("Models.xml")
            End If
        End Sub
    End Module
  2. Save the file
  3. Open  the Command Prompt and Change to the Directory that contains the above file, CPAP1
  4. To compile the exercise, type vbc Exercise.vb and press Enter
  5. To execute the application, type Exercise and press Enter
  6. Using the menu, try adding a few car manufacturers (like Toyota and Honda) and a few makes (like Neon, Civic, Camry, and Spider) 
  7. Return to Notepad

Adding a Filled Child Element

The above Holidays.xml file had only one level under the root and no child element of the root had children. Suppose you have a file as follows:

<?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 Mins</Length>
    <Format>DVD</Format>
    <Rating>PG-13</Rating>
  </Video>
</Videos>

Imagine that you want to add a Video element. You have a choice of adding one, more, or all child elements of the Video node. To perform this operation, one solution you can use is to "build" all child elements of the Video element, then add the node as a whole. To support this technique, we saw earlier that the XmlNode.InnerXml property comprises a node, its markup, its children and their markup. This means that you can create the child nodes with their markup(s) as a string and assign that string to an XmlNode.InnerXml string. To do this, you would need the set version of the InnerXml property. It is declared as follows:

public virtual string InnerXml{get; set;}

Here is an example that adds a complete new Video node to the above XML file:

static void DoIt()
{
	 XmlDocument docXML = new XmlDocument();
	 docXML.Load("Videos.xml");

	 XmlElement elmXML = docXML.CreateElement("Video");
	 string strNewVideo = "<Title>Other People's Money</Title>" +
		                      "<Director>Alan Brunstein</Director>" +
			      "<Length>114 Minutes</Length>" +
			      "<Format>VHS</Format>" +
			      "<Rating>PG-13</Rating>";

	 elmXML.InnerXml = strNewVideo;
	 docXML.DocumentElement.AppendChild(elmXML);

	 docXML.Save("Videos.xml");
}

If you have an XML file with different levels and you want to add an element as a new child to a particular element, you can first locate that element. One way you can do this is to call the XmlDocument.GetElementByTagName() method. This method is overloaded with two versions. One of its versions has the following syntax:

public virtual XmlNodeList GetElementsByTagName(string name);

This method takes as argument the name of the element that you want to locate. If the method finds that element, it returns a list of all child nodes of that element as an XmlNodeList object. This XmlNodeList object represents a collection of nodes where each node can be located by its index through the ItemOf indexed property.

 

Practical Learning Practical Learning: Adding Elements

  1. To allow the user to create new parts, change the source code as follows:
     
    Imports System
    Imports System.xml
    
    Module Exercise
        
        Public Sub Main()
    
            Dim mnuChoice As Char = "q"
    
            Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=")
            Console.WriteLine("=-= College Park Auto-Parts =-=")
            Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=")
    
            Do
                Console.WriteLine("=-= Main Menu =-=")
                Console.WriteLine("0 - Exit")
                Console.WriteLine("1 - Add New Car Make")
                Console.WriteLine("2 - Add New Car Model")
                Console.WriteLine("3 - Add New Car Part")
                Console.Write("Your Choice: ")
                mnuChoice = Char.Parse(Console.ReadLine())
    
                If mnuChoice = "1" Then
                    CreateNewMake()
                ElseIf mnuChoice = "2" Then
                    CreateNewModel()
                ElseIf mnuChoice = "3" Then
                    AddNewPart()
                End If
    
                If (mnuChoice <> "0") And (mnuChoice <> "1") And _
                   (mnuChoice <> "2") And (mnuChoice <> "3") Then
                    Console.WriteLine("Invalid Choice: Please try again")
                End If
            Loop While (mnuChoice <> "0")
    
            Console.WriteLine("Thank you!")
        End Sub
    
        Private Sub CreateNewMake()
            Dim strNewMake As String
    
            Console.Write("Enter Car Make: ")
            strNewMake = Console.ReadLine()
    
            ' Open the Makes.xml file
            Dim docXMLFile As XmlDocument = New XmlDocument
            docXMLFile.Load("Makes.xml")
    
            ' Get the root node so we can explore its children
            Dim nodRoot As XmlElement = docXMLFile.DocumentElement
            ' Store all the values of the elements in a string
            Dim allMyChildren As String = nodRoot.InnerText
            ' Locate the new make among the values of the elements
            Dim indexLookForNewMake As Integer = allMyChildren.IndexOf(strNewMake)
    
            ' If the car make exists already, don't add it
            If indexLookForNewMake >= 0 Then
                Exit Sub
            Else
                ' If the car is not in the list already, add it as a Make element
                Dim elmXML As XmlElement = docXMLFile.CreateElement("Make")
                ' Create its value using the string provided by the user
                Dim txtXML As XmlText = docXMLFile.CreateTextNode(strNewMake)
                ' Add the new element at the end of the file
                docXMLFile.DocumentElement.AppendChild(elmXML)
                ' Specify its text
                docXMLFile.DocumentElement.LastChild.AppendChild(txtXML)
    
                ' Save the file
                docXMLFile.Save("Makes.xml")
            End If
        End Sub
    
        Private Sub CreateNewModel()
            Dim strNewModel As String = Nothing
    
            Console.Write("Enter Car Model: ")
            strNewModel = Console.ReadLine()
    
            Dim docXMLFile As XmlDocument = New XmlDocument
            docXMLFile.Load("Models.xml")
    
            Dim nodRoot As XmlElement = docXMLFile.DocumentElement
            Dim allMyChildren As String = nodRoot.InnerText
            Dim indexNewModel As Integer = allMyChildren.IndexOf(strNewModel)
    
            If indexNewModel >= 0 Then
                Exit Sub
            Else
                Dim elmXML As XmlElement = docXMLFile.CreateElement("Model")
                Dim txtXML As XmlText = docXMLFile.CreateTextNode(strNewModel)
    
                docXMLFile.DocumentElement.AppendChild(elmXML)
                docXMLFile.DocumentElement.LastChild.AppendChild(txtXML)
    
                docXMLFile.Save("Models.xml")
            End If
        End Sub
    
    
        Private Sub AddNewPart()
            Dim carYear As Integer
            Dim strModel As String
            Dim strMake As String
            Dim strPartNumber As String
            Dim strPartName As String
            Dim unitPrice As Double
    
            ' - Generate a random number between 100000 and 999999 - 
    
            ' We will generate a random number for the item
            ' To start, we will use the miliseconds as a seed
            Dim ms As Integer = DateTime.Now.Millisecond
            Dim rndNumber As Random = New Random(ms)
            Dim nxtNumber As Integer = rndNumber.Next(100000, 999999)
            ' Display the new number in the Part # text box
            strPartNumber = CStr(nxtNumber)
    
            ' - Let the user specify the car model year - 
            Dim curYear As Integer = DateTime.Now.Year + 1
    
            Console.WriteLine("Enter the following information as is related to the new car part")
            Console.WriteLine("For the car model that the new part is made for, enter the year")
            Console.Write("between 1960 and " & CStr(curYear) & ": ")
            carYear = CInt(Console.ReadLine())
    
            ' - Display the list of Makes to the user to select one - 
            ' We will need a reference to the XML document
            Dim docXML As XmlDocument = New XmlDocument
    
            ' Open the Makes.xml file
            docXML.Load("Makes.xml")
    
            ' Get a reference to the root node
            Dim nodRoot As XmlElement = docXML.DocumentElement
            ' Locate all nodes whose name is Make
            Dim nodItems As XmlNodeList = nodRoot.GetElementsByTagName("Make")
            ' Retrieve the value of each Make node and display
            ' that value to the user
            Console.WriteLine("Here is a list of the car makes in our system")
            For Each nodItem As XmlNode In nodItems
                Console.WriteLine(nodItem.InnerXml)
            Next
            Console.Write("From this list, enter the car make of the new part: ")
            strMake = Console.ReadLine()
            Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
    
            ' - Display the list of car Models to the user to select one -
            ' Open the Models.xml file
            docXML.Load("Models.xml")
    
            ' Get a reference to the root node
            nodRoot = docXML.DocumentElement
            ' Locate all nodes whose name is Model
            nodItems = nodRoot.GetElementsByTagName("Model")
            ' Retrieve the value of each Model node and display
            ' that value to the user
            Console.WriteLine("Here is a list of the car models in our system")
            For Each nodItem As XmlNode In nodItems
                Console.WriteLine(nodItem.InnerXml)
            Next
    
            Console.Write("From this list, enter the car model of the part: ")
            strModel = Console.ReadLine()
            Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
    
            ' - Request the part name -
            Console.Write("Enter Part Name:  ")
            strPartName = Console.ReadLine()
    
            ' - Request the unit price -
            Console.Write("Enter Unit Price: ")
            unitPrice = Double.Parse(Console.ReadLine())
    
            Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
            Console.WriteLine("New Car Part Summary")
            Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
            Console.WriteLine("Part #:     " + strPartNumber)
            Console.WriteLine("Model Year: " + carYear)
            Console.WriteLine("Car Make:   " + strMake)
            Console.WriteLine("Car Model:  " + strModel)
            Console.WriteLine("Part Name:  " + strPartName)
            Console.WriteLine("Unit Price: " + unitPrice)
            Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=")
    
            ' XmlDocument docXML = new XmlDocument()
            docXML.Load("Parts.xml")
    
            Dim elmXML As XmlElement = docXML.CreateElement("Part")
            Dim strNewPart As String = "<PartNumber>" & strPartNumber & "</PartNumber>" & _
                                     "<CarYear>" & CStr(carYear) & "</CarYear>" & _
                                     "<Make>" & strMake & "</Make>" & _
                       "<Model>" & strModel & "</Model>" & _
                       "<PartName>" & strPartName & "</PartName>" & _
                       "<UnitPrice>" & CStr(unitPrice) & "</UnitPrice>"
    
            elmXML.InnerXml = strNewPart
            docXML.DocumentElement.AppendChild(elmXML)
    
            docXML.Save("Parts.xml")
        End Sub
    
    End Module
  2. Save the file and return to the Command Prompt
  3. To compile the exercise, type vbc Exercise.vb and press Enter
  4. To execute the application, type Exercise and press Enter
  5. Using the menu, try adding a few car parts. Here are examples:
     
    =o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=
    =-= College Park Auto-Parts =-=
    =o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=
    =-= Main Menu =-=
    0 - Exit
    1 - Add New Car Make
    2 - Add New Car Model
    3 - Add New Car Part
    Your Choice: 3
    Enter the following information as is related to the new car part
    For the car model that the new part is made for, enter the year
    between 1960 and 2006: 1996
    Here is a list of the car makes in our system
    Acura
    BMW
    Dodge
    Toyota
    Honda
    Hyundai
    From this list, enter the car make of the new part: Dodge
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Here is a list of the car models in our system
    NSX
    TL
    Spider
    A4
    RS6
    323I
    M5
    Neon
    Civic
    Camry
    From this list, enter the car model of the part: Neon
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Enter Part Name:  Brake Pads
    Enter Unit Price: 34.95
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    New Car Part Summary
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Part #:     973417
    Model Year: 1996
    Car Make:   Dodge
    Car Model:  Neon
    Part Name:  Brake Pads
    Unit Price: 34.95
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    =-= Main Menu =-=
    0 - Exit
    1 - Add New Car Make
    2 - Add New Car Model
    3 - Add New Car Part
    Your Choice: 3
    Enter the following information as is related to the new car part
    For the car model that the new part is made for, enter the year
    between 1960 and 2006: 1996
    Here is a list of the car makes in our system
    Acura
    BMW
    Dodge
    Toyota
    Honda
    Hyundai
    From this list, enter the car make of the new part: Honda
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Here is a list of the car models in our system
    NSX
    TL
    Spider
    A4
    RS6
    323I
    M5
    Neon
    Civic
    Camry
    From this list, enter the car model of the part: Civic
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Enter Part Name:  Passenger Mirror
    Enter Unit Price: 24.65
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    New Car Part Summary
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Part #:     719266
    Model Year: 1996
    Car Make:   Honda
    Car Model:  Civic
    Part Name:  Passenger Mirror
    Unit Price: 24.65
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    =-= Main Menu =-=
    0 - Exit
    1 - Add New Car Make
    2 - Add New Car Model
    3 - Add New Car Part
    Your Choice: 3
    Enter the following information as is related to the new car part
    For the car model that the new part is made for, enter the year
    between 1960 and 2006: 1998
    Here is a list of the car makes in our system
    Acura
    BMW
    Dodge
    Toyota
    Honda
    Hyundai
    From this list, enter the car make of the new part: Honda
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Here is a list of the car models in our system
    NSX
    TL
    Spider
    A4
    RS6
    323I
    M5
    Neon
    Civic
    Camry
    From this list, enter the car model of the part: Civic
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Enter Part Name:  Brake Pads
    Enter Unit Price: 34.85
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    New Car Part Summary
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Part #:     879207
    Model Year: 1998
    Car Make:   Honda
    Car Model:  Civic
    Part Name:  Brake Pads
    Unit Price: 34.85
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    =-= Main Menu =-=
    0 - Exit
    1 - Add New Car Make
    2 - Add New Car Model
    3 - Add New Car Part
    Your Choice: 0
    Thank you!
  6. Type Exit and press Enter to close the DOS window
  7. Close Notepad to end the lesson

Element Navigation

An XML tree navigation consists of visiting the various nodes of the file, for any necessary reason. One reason would be that you want to insert a new element at a specific position in the tree. Another would be that you want to check whether a certain node is already present in the tree.

As always, there are various ways you can perform an operation such as navigating a tree. To "scan" a file from top to bottom, thus visiting each type of node in the XML file, you can use the XmlTextReader class. This class is equipped with all types of properties and methods you would need.

If you want to navigate to a specific node in the tree, you can use the XmlDocument.GetElementByTagName() method that we used previously.

 

Previous Copyright © 2005-2016, FunctionX Next