Visual Basic 2005 XML Programming Using XML DOM

This article mainly focuses on manipulating XML documents using the XML API available in the .NET Framework. In simple terms, we will design a Windows Form and do all CRUD operations against an existing XML document.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 3
November 26, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

To make the article simple, I designed a Windows Form as follows.


The entire source code for this article is available in the form of a free downloadable zip file. The solution was developed using Microsoft Visual Studio 2005 on Microsoft Windows Server 2003 Standard Edition (with SP3). I didn't really test it in any other environment. I request that you post in the discussion area if you have any problems in execution.

Understanding the structure of the sample XML document

Before we start manipulating the XML document, we should fully understand the content and structure of the XML document on which we are working. Let us try to understand the structure of the sample XML document from the following figure.


The above would read something like the following:

A company has a few departments. Each department has information about its number, name, location and a few employees working in the same. Similarly, all employee information is maintained with an ID, number, name, salary and department number.

The starting point (say root) of the document is company (or "CompanyInfo"). All of the departments in the company are maintained (encapsulated) in a single unit named "DepartmentInfo." The "DepartmentInfo" contains a group of departments. Each piece of department information starts with a "Department" tag (or element). Every "Department" also has an "ID" as attribute and a group of elements directly beneath it. The tags "Deptno," "Dname," "Location" and "EmployeeInfo" are direct descendants of the "Department" tag. The "EmployeeInfo" contains a group of employees (along with their information). Every employee and his information ("Empno," "Ename," "Sal" and "Deptno") is embedded in a single parent element named "Employee," which is again a direct descendant to the "EmployeeInfo" element.

Sample XML document: source

Now that we understand the structure of the sample XML document (from the previous section), we need to have some sample XML data to work with .NET.

The following is the XML source used as a sample in the .NET application. It follows the same structure as explained in the previous section. I named it  MyXML.xml.


<?xml version="1.0" encoding="utf-8"?>

<CompanyInfo>

<DepartmentInfo>

<!-- contains all departments and employees-->

<Department ID="D10">

<Deptno>10</Deptno>

<Dname>Accounting</Dname>

<Location>Dallas</Location>

<EmployeeInfo>

<Employee ID="E1">

<Empno>1001</Empno>

<Ename>Jag</Ename>

<Sal>2300</Sal>

<Deptno>10</Deptno>

</Employee>

<Employee ID="E2">

<Empno>1002</Empno>

<Ename>Chat</Ename>

<Sal>3400</Sal>

<Deptno>10</Deptno>

</Employee>

<Employee ID="E3">

<Empno>1003</Empno>

<Ename>Winner</Ename>

<Sal>4500</Sal>

<Deptno>10</Deptno>

</Employee>

</EmployeeInfo>

</Department>

<Department ID="D20">

<Deptno>20</Deptno>

<Dname>Sales</Dname>

<Location>New York</Location>

<EmployeeInfo>

<Employee ID="E4">

<Empno>1004</Empno>

<Ename>Ram</Ename>

<Sal>3400</Sal>

<Deptno>20</Deptno>

</Employee>

<Employee ID="E5">

<Empno>1005</Empno>

<Ename>Raj</Ename>

<Sal>4500</Sal>

<Deptno>20</Deptno>

</Employee>

</EmployeeInfo>

</Department>

<Department ID="D30">

<Deptno>30</Deptno>

<Dname>Production</Dname>

<Location>DC</Location>

<EmployeeInfo>

<Employee ID="E6">

<Empno>1006</Empno>

<Ename>aaa</Ename>

<Sal>3400</Sal>

<Deptno>30</Deptno>

</Employee>

<Employee ID="E7">

<Empno>1007</Empno>

<Ename>bbb</Ename>

<Sal>4300</Sal>

<Deptno>30</Deptno>

</Employee>

</EmployeeInfo>

</Department>

<Department ID="D40">

<Deptno>40</Deptno>

<Dname>IT</Dname>

<Location>LA</Location>

<EmployeeInfo>

<Employee ID="E8">

<Empno>1008</Empno>

<Ename>xxx</Ename>

<Sal>2900</Sal>

<Deptno>40</Deptno>

</Employee>

<Employee ID="E9">

<Empno>1009</Empno>

<Ename>yyy</Ename>

<Sal>4600</Sal>

<Deptno>40</Deptno>

</Employee>

</EmployeeInfo>

</Department>

</DepartmentInfo>

</CompanyInfo>


Loading/Searching an XML document with XML DOM using Visual Basic.NET

The starting point for learning XML programming is to load the XML document into an object. Let us look at that:


Const XMLDOCFILEPATH As String = "....MyData.xml"

Dim doc As XmlDocument

doc = New XmlDocument

doc.Load(XMLDOCFILEPATH)


In the above code, I am creating a new XMLDocument object and loading XML into it. Make sure that you import "System.XML" before you work on XML-related classes.

Once the XML is loaded into the "XMLDocument" object, we can mold it to any kind of object. For instance, we can create a strongly typed data table using the following code:


Dim nEmps As XmlNodeList = doc.SelectNodes("//Employee")

Dim dt As New DataTable

dt.Columns.Add("ID")

dt.Columns.Add("Empno")

dt.Columns.Add("Ename")

dt.Columns.Add("Sal")

dt.Columns.Add("Deptno")

For Each nEmp As XmlElement In nEmps

Dim dr As DataRow = dt.NewRow

dr("ID") = nEmp.GetAttribute("ID")

dr("Empno") = nEmp.ChildNodes(0).InnerText

dr("Ename") = nEmp.ChildNodes(1).InnerText

dr("Sal") = nEmp.ChildNodes(2).InnerText

dr("Deptno") = nEmp.ChildNodes(3).InnerText

dt.Rows.Add(dr)

Next


The alternative way to achieve something similar to the above is by using "Dataset.ReadXml."

If you observe the above code snippet, I used "//Employee" to retrieve only "Employee" elements (along with their child elements). "//Employee" is an XPath expression. XPath is a simple "search" kind of technology for XML. It has its own operators and syntax. By using XPath expressions we can retrieve/find any part of the provided XML.

Let us consider finding single employee information (using XPath) based on the employee number provided. The following is the code:


Dim nEmp As XmlElement = doc.SelectSingleNode("//Employee[Empno='1007']")


Once the employee is found, we can retrieve information about its child elements as follows:


a = nEmp.SelectSingleNode("Ename").InnerText

b = nEmp.SelectSingleNode("Sal").InnerText

c = nEmp.SelectSingleNode("Deptno").InnerText

d = nEmp.GetAttribute("ID")


Adding, Updating and Deleting From the XML Document with XML DOM Using Visual Basic.NET

In the previous section, we have seen how to retrieve and search an XML document using XML DOM. In this section we will manipulate the XML document with Add, Update and Delete operations.

Let us consider adding a new employee to department 30. The following is the sample code:


Dim nEmpInfo As XmlNode = doc.SelectSingleNode("//Department[Deptno='30']/EmployeeInfo")

Dim nEmployee As XmlNode = doc.CreateElement("Employee")

Dim nEmpno As XmlNode = doc.CreateElement("Empno")

Dim nEname As XmlNode = doc.CreateElement("Ename")

Dim nSal As XmlNode = doc.CreateElement("Sal")

Dim nDeptno As XmlNode = doc.CreateElement("Deptno")

Dim aID As XmlAttribute = doc.CreateAttribute("ID")


'assign values to elements

nEmpno.InnerText = "4001"

nEname.InnerText = "Winner"

nSal.InnerText = "4500"

nDeptno.InnerText = "30"

aID.InnerText = "E20"


'form the node structure

With nEmployee

.Attributes.Append(aID)

.AppendChild(nEmpno)

.AppendChild(nEname)

.AppendChild(nSal)

.AppendChild(nDeptno)

End With


nEmpInfo.AppendChild(nEmployee)


Similarly, we can also modify existing record information using the following code:


Dim nEmp As XmlElement = doc.SelectSingleNode("//Employee[Empno='4001']")

nEmp.SelectSingleNode("Ename").InnerText = "Winner2"

nEmp.SelectSingleNode("Sal").InnerText = "5400" 

nEmp.SelectSingleNode("Deptno").InnerText = "30"

nEmp.SetAttribute("ID", "E40")


In the same manner, we can use the following code to delete existing record:


Dim nEmp As XmlElement = doc.SelectSingleNode("//Employee[Empno='4001']")

Dim nEmpInfo As XmlElement = nEmp.SelectSingleNode("ancestor::EmployeeInfo")

nEmpInfo.RemoveChild(nEmp)


Finally, we can save the XML document back to the file using the following code:


doc.Save(XMLDOCFILEPATH)


Developing a complete form to work with XML DOM using Visual Basic.NET


To demonstrate all of the previous concepts, I designed a Windows form for CRUD operations as shown in Fig 1. The following is the code developed for the form:


Imports System.Xml


Public Class Form1


Const XMLDOCFILEPATH As String = "....MyData.xml"


Dim doc As New XmlDocument


Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click

Dim nEmp As XmlElement = doc.SelectSingleNode(String.Format("//Employee[Empno='{0}']", Me.txtEmpno.Text))

If nEmp Is Nothing Then

MessageBox.Show("Not found")

Exit Sub

End If


Me.txtEname.Text = nEmp.SelectSingleNode("Ename").InnerText

Me.txtSal.Text = nEmp.SelectSingleNode("Sal").InnerText

Me.txtDeptno.Text = nEmp.SelectSingleNode("Deptno").InnerText

Me.txtID.Text = nEmp.GetAttribute("ID")

End Sub


Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

RefreshXMLDoc()

End Sub


Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click

For Each c As Control In Me.Controls

If TypeOf c Is TextBox Then

CType(c, TextBox).Text = ""

End If

Next

End Sub


Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click

'go to the EmployeeInfo node of provided department

Dim nEmpInfo As XmlNode = doc.SelectSingleNode(String.Format("//Department[Deptno='{0}']/EmployeeInfo", Me.txtDeptno.Text))

If nEmpInfo Is Nothing Then

MessageBox.Show("Department/EmployeeInfo not found")

Exit Sub

End If


'create elements of node structure

Dim nEmployee As XmlNode = doc.CreateElement("Employee")

Dim nEmpno As XmlNode = doc.CreateElement("Empno")

Dim nEname As XmlNode = doc.CreateElement("Ename")

Dim nSal As XmlNode = doc.CreateElement("Sal")

Dim nDeptno As XmlNode = doc.CreateElement("Deptno")

Dim aID As XmlAttribute = doc.CreateAttribute("ID")


'assign values to elements

nEmpno.InnerText = Me.txtEmpno.Text

nEname.InnerText = Me.txtEname.Text

nSal.InnerText = Me.txtSal.Text

nDeptno.InnerText = Me.txtDeptno.Text

aID.InnerText = Me.txtID.Text


'form the node structure

With nEmployee

.Attributes.Append(aID)

.AppendChild(nEmpno)

.AppendChild(nEname)

.AppendChild(nSal)

.AppendChild(nDeptno)

End With


nEmpInfo.AppendChild(nEmployee)

SaveXMLDoc()

MessageBox.Show("Added Successfully!")


End Sub


Private Sub SaveXMLDoc()

doc.Save(XMLDOCFILEPATH)

RefreshXMLDoc()

btnClear_Click(Nothing, Nothing)

End Sub


Private Sub RefreshXMLDoc()

doc = New XmlDocument

doc.Load(XMLDOCFILEPATH)

btnRefresh_Click(Nothing, Nothing)

End Sub


Developing a complete form to work with XML DOM using Visual Basic.NET: continued


The following is a continuation from the previous section.


Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click

Dim nEmp As XmlElement = doc.SelectSingleNode(String.Format("//Employee[Empno='{0}']", Me.txtEmpno.Text))

If nEmp Is Nothing Then

MessageBox.Show("Not found")

Exit Sub

End If


If nEmp.SelectSingleNode("Deptno").InnerText.Equals(Me.txtDeptno.Text) Then

''The following would simply modify and update the record

''However, it would not detach and attach to another dept branch (if dept is different)

nEmp.SelectSingleNode("Ename").InnerText = Me.txtEname.Text

nEmp.SelectSingleNode("Sal").InnerText = Me.txtSal.Text

nEmp.SelectSingleNode("Deptno").InnerText = Me.txtDeptno.Text 'this is not necessary

nEmp.SetAttribute("ID", Me.txtID.Text)

Else

'go to the EmployeeInfo node of provided department

Dim nTargetEmpInfo As XmlNode = doc.SelectSingleNode(String.Format("//Department[Deptno='{0}']/EmployeeInfo", Me.txtDeptno.Text))

If nTargetEmpInfo Is Nothing Then

MessageBox.Show("Department/EmployeeInfo not found")

Exit Sub

End If


'remove node from current location

Dim nSourceEmpInfo As XmlElement = nEmp.SelectSingleNode("ancestor::EmployeeInfo")

nSourceEmpInfo.RemoveChild(nEmp)


'adding node to new location

'create elements of node structure

Dim nEmployee As XmlNode = doc.CreateElement("Employee")

Dim nEmpno As XmlNode = doc.CreateElement("Empno")

Dim nEname As XmlNode = doc.CreateElement("Ename")

Dim nSal As XmlNode = doc.CreateElement("Sal")

Dim nDeptno As XmlNode = doc.CreateElement("Deptno")

Dim aID As XmlAttribute = doc.CreateAttribute("ID")

'assign values to elements

nEmpno.InnerText = Me.txtEmpno.Text

nEname.InnerText = Me.txtEname.Text

nSal.InnerText = Me.txtSal.Text

nDeptno.InnerText = Me.txtDeptno.Text

aID.InnerText = Me.txtID.Text

'form the node structure

With nEmployee

.Attributes.Append(aID)

.AppendChild(nEmpno)

.AppendChild(nEname)

.AppendChild(nSal)

.AppendChild(nDeptno)

End With

nTargetEmpInfo.AppendChild(nEmployee)


End If



SaveXMLDoc()

MessageBox.Show("Updated Successfully!")

End Sub



Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click

Dim nEmp As XmlElement = doc.SelectSingleNode(String.Format("//Employee[Empno='{0}']", Me.txtEmpno.Text))

If nEmp Is Nothing Then

MessageBox.Show("Not found")

Exit Sub

End If

Dim nEmpInfo As XmlElement = nEmp.SelectSingleNode("ancestor::EmployeeInfo")

nEmpInfo.RemoveChild(nEmp)

SaveXMLDoc()

MessageBox.Show("Deleted Successfully!")


End Sub


Private Sub btnRefresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefresh.Click

Dim nEmps As XmlNodeList = doc.SelectNodes("//Employee")

Dim dt As New DataTable

dt.Columns.Add("ID")

dt.Columns.Add("Empno")

dt.Columns.Add("Ename")

dt.Columns.Add("Sal")

dt.Columns.Add("Deptno")

For Each nEmp As XmlElement In nEmps

Dim dr As DataRow = dt.NewRow

dr("ID") = nEmp.GetAttribute("ID")

dr("Empno") = nEmp.ChildNodes(0).InnerText

dr("Ename") = nEmp.ChildNodes(1).InnerText

dr("Sal") = nEmp.ChildNodes(2).InnerText

dr("Deptno") = nEmp.ChildNodes(3).InnerText

dt.Rows.Add(dr)

Next

Me.DataGridView1.DataSource = dt

End Sub

End Class

My next upcoming article will focus on LINQ to XML. I hope you enjoyed the article and any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com

blog comments powered by Disqus
WINDOWS SCRIPTING ARTICLES

- More Windows Scripting Workarounds from Nilpo
- Overloading Methods and More in VBScript
- Improving MFC for Windows Vista
- Regular Expressions in VBScript
- Working with Dates in WMI
- Completing Calendars with VBScript Date Func...
- Building Calendars with VBScript Date Functi...
- Working With Dates and Times in VBScript
- Designing WCF DataContract Classes Using the...
- Understanding Dates and Times in VBScript
- Working With Arrays in VBScript
- Compressed Folders in WSH
- Using .NET Interops in VBScript
- Nilpo`s Scripting Secrets, Vol I
- Database operations using Silverlight 2.0 WC...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 6 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials