Click here to Skip to main content
Click here to Skip to main content
Go to top

Parse XML Documents by XMLDocument and XDocument

, 5 Apr 2011
Rate this:
Please Sign up or sign in to vote.
This article demonstrates how to parse XML documents using "XMLDocument" as well as "XDocument".

Introduction

This article demonstrates how to parse XML documents using "XMLDocument" as well as "XDocument".

Background

"XML" and the parsing of XML documents are very old topics and it is not very common for us to directly work on XML documents. But once in a while, you may find that you are given some raw XML documents and you need to parse them. This article is to demonstrate how to use the two commonly used .NET utility classes "XMLDocument" and "XDocument" to parse XML documents.

Solution.JPG

The attached Visual Studio 2010 solution has two projects:

  • The "XMLWebRepository" project is an ASP.NET web project. The "Student.xml" file in this project is the XML file used in the demonstration.
  • The "XMLParsingExample" project is a simple WPF "MVVM" application. We will be using this application to demonstrate how to parse XML documents using "XMLDocument" as well as "XDocument".

Let us first take a look at the "XMLWebRepository" project and the XML document "Student.xml".

The XML Document to Parse

The XML document used in this demo is in the "Student.xml" file in the "XMLWebRepository" project:

<?xml version="1.0" encoding="utf-8" ?>
<StudentsInformation>
  <GeneralInformation>
    <School>University of XML</School>
    <Department>Department of XML parsing</Department>
  </GeneralInformation>
  <Studentlist>
    <Student id="1" score="100" enrollment="4/30/1789"
             comment="1st and greatest president">George Washington</Student>
    <Student id="2" score="100" enrollment="3/4/1861"
             comment="Civil was. Great president!">Abraham Lincoln</Student>
    <Student id="3" score="99" enrollment="1/20/1993"
             comment="Monica Samille Lewinsky, Cool!">Bill J. Clinton</Student>
    <Student id="4" score="98" enrollment="1/20/2001" 
             comment="House price went beyond American's affordability">
		George W. Bush</Student>
    <Student id="5" score="99" enrollment="1/20/2009" comment=
             "Ridiculously low interest rate, high house price. $ worthless">
		Barack H. Obama</Student>
    <Student id="6" score="35" enrollment="4/30/2011" 
             comment="Never qualified to be the president.">Song Li</Student>
  </Studentlist>
</StudentsInformation>

If you right click the "Student.xml" file in the solution explorer and select "View in Browser", a web browser is shown as the following:

XMLInBrowser.JPG

You should pay some attention to the URL "http://localhost:7467/Student.xml" in the address bar. This is the URL that the "XMLParsingExample" project will be using to load the XML document. Let us now take a look at the "XMLParsingExample" project on how we will parse the "Student.xml" using "XMLDocument" and "XDocument".

Parse the XML Document

In the "XMLParsingExample" project, in order to save the result from parsing the "Student.xml", two classes are created in the "ApplicationModel.cs" file in the "Models" folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
 
namespace XMLParsingExample.Models
{
    public class Student
    {
        public int id { get; set; }
        public string name { get; set; }
        public int score { get; set; }
        public string enrollment { get; set; }
        public string comment { get; set; }
    }
 
    public class StudentsInformation
    {
        public string School { get; set; }
        public string Department { get; set; }
        public List<Student> Studentlist { get; set; }
 
        public StudentsInformation()
        {
            School = "N/A";
            Department = "N/A";
            Studentlist = new List<Student>();
        }
    }
}

You may have noticed that the two classes are directly related to the information in the "Student.xml" file. We will read the information in the "Student.xml" file and save the information into an object of the "StudentsInformation" class. The code that demonstrates how to parse the XML document is implemented in the "XMLParsers.cs" file in the "Models" folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
 
namespace XMLParsingExample.Models
{
    public static class XMLParsers
    {
        private static string xmlUrl = "http://localhost:7467/Student.xml";
 
        // Parse the xml using XMLDocument class.
        public static StudentsInformation ParseByXMLDocument()
        {
            var students = new StudentsInformation();
 
            XmlDocument doc = new XmlDocument();
            doc.Load(xmlUrl);
 
            XmlNode GeneralInformationNode =
                doc.SelectSingleNode("/StudentsInformation/GeneralInformation");
            students.School =
                GeneralInformationNode.SelectSingleNode("School").InnerText;
            students.Department =
                GeneralInformationNode.SelectSingleNode("Department").InnerText;
 
            XmlNode StudentListNode =
                doc.SelectSingleNode("/StudentsInformation/Studentlist");
            XmlNodeList StudentNodeList =
                StudentListNode.SelectNodes("Student");
            foreach (XmlNode node in StudentNodeList)
            {
                Student aStudent = new Student();
                aStudent.id = Convert.ToInt16(node.Attributes
                    .GetNamedItem("id").Value);
                aStudent.name = node.InnerText;
                aStudent.score = Convert.ToInt16(node.Attributes
                    .GetNamedItem("score").Value);
                aStudent.enrollment =
                    node.Attributes.GetNamedItem("enrollment").Value;
                aStudent.comment =
                    node.Attributes.GetNamedItem("comment").Value;
 
                students.Studentlist.Add(aStudent);
            }
 
            return students;
        }
 
        // Parse the XML using XDocument class.
        public static StudentsInformation ParseByXDocument()
        {
            var students = new StudentsInformation();
 
            XDocument doc = XDocument.Load(xmlUrl);
            XElement generalElement = doc
                    .Element("StudentsInformation")
                    .Element("GeneralInformation");
            students.School = generalElement.Element("School").Value;
            students.Department = generalElement.Element("Department").Value;
 
            students.Studentlist = (from c in doc.Descendants("Student")
                           select new Student()
                           {
                               id = Convert.ToInt16(c.Attribute("id").Value),
                               name = c.Value,
                               score = Convert.ToInt16(c.Attribute("score").Value),
                               enrollment = c.Attribute("enrollment").Value,
                               comment = c.Attribute("comment").Value
                           }).ToList<Student>();
 
            return students;
        }
    }
}

The static class "XMLParsers" implements two static methods:

  • The "ParseByXMLDocument" method shows how to parse the XML document using "XMLDocument".
  • The "ParseByXDocument" method shows how to parse the XML document using "XDocument".

The two methods are very similar, but the "linq" flavored "XDocument" enables us to save a couple of lines of C# code. Both the methods are pretty simply and you should not have much problem to read them. If you are only interested in how to parse XML documents, you can skip the rest of the article. But to make this demo a "running" example, I will give some brief overall introduction to the "XMLParsingExample" project.

The "XMLParsingExample" Application

The "XMLParsingExample" project is a WPF MVVM application. I have a dedicated article "Data and Command Bindings for Silverlight MVVM Applications" to discuss how to implement the data and command bindings in the MVVM applications. If you are interested, you can take a look at it and it should make your reading of the rest of this article much easier. To help the implementation of the "XMLParsingExample" application, I implemented two utility classes in the "BindingUtilities.cs" file in the "MVVMUtilities" folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.ComponentModel;
using System.Windows.Input;
 
namespace XMLParsingExample.MVVMUtilities
{
    public abstract class ViewModelBase
        : DependencyObject, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
 
    public class RelayCommand : ICommand
    {
        private readonly Action handler;
        private bool isEnabled;
 
        public RelayCommand(Action handler)
        {
            this.handler = handler;
        }
 
        public bool IsEnabled
        {
            get { return isEnabled; }
            set
            {
                if (value != isEnabled)
                {
                    isEnabled = value;
                    if (CanExecuteChanged != null)
                    {
                        CanExecuteChanged(this, EventArgs.Empty);
                    }
                }
            }
        }
 
        public bool CanExecute(object parameter)
        {
            return IsEnabled;
        }
 
        public event EventHandler CanExecuteChanged;
 
        public void Execute(object parameter)
        {
            handler();
        }
    }
}

The "ViewModelBase" class will be the base class for all the view models in the MVVM application, and the "RelayCommand" class will be used to implement "Commands" in the view models. The simple view model of the "XMLParsingExample" application is implemented in the "MainWindowViewModel.cs" file in the "ViewModels" folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XMLParsingExample.MVVMUtilities;
using XMLParsingExample.Models;
 
namespace XMLParsingExample.ViewModels
{
    class MainWindowViewModel : ViewModelBase
    {
        // Properties
        private StudentsInformation studentInformation;
        public StudentsInformation StudentInformationObject
        {
            get { return studentInformation; }
            private set
            {
                studentInformation = value;
                NotifyPropertyChanged("StudentInformationObject");
            }
        }
 
        private void InitiateState()
        {
            studentInformation = new StudentsInformation();
        }
 
        // Commands
        public RelayCommand ClearResultCommand { get; private set; }
        private void ClearResult()
        {
            StudentInformationObject = new StudentsInformation();
        }
 
        public RelayCommand XMLDocumentLoadCommand { get; private set; }
        private void XMLDocumentLoad()
        {
            StudentInformationObject = XMLParsers.ParseByXMLDocument();
        }
 
        public RelayCommand XDocumentLoadCommand { get; private set; }
        private void XDocumentLoad()
        {
            StudentInformationObject = XMLParsers.ParseByXDocument();
        }
 
        private void WireCommands()
        {
            ClearResultCommand = new RelayCommand(ClearResult);
            ClearResultCommand.IsEnabled = true;
 
            XMLDocumentLoadCommand = new RelayCommand(XMLDocumentLoad);
            XMLDocumentLoadCommand.IsEnabled = true;
 
            XDocumentLoadCommand = new RelayCommand(XDocumentLoad);
            XDocumentLoadCommand.IsEnabled = true;
        }
 
        // Constructor
        public MainWindowViewModel()
        {
            InitiateState();
            WireCommands();
        }
    }
}

This view model class implemented one public property and three commands:

  • The "StudentInformationObject" property is used to keep the information from parsing the "Student.xml" file.
  • The "XMLDocumentLoadCommand" command parses the "Student.xml" file using "XMLDocument" by calling the "ParseByXMLDocument" method in the "XMLParsers" class.
  • The "XDocumentLoadCommand" command parses the "Student.xml" file using "XDocument" by calling the "ParseByXDocument" method in the "XMLParsers" class.
  • The "ClearResultCommand" command clears the "StudentInformationObject" property.

This view model is bound to the "MainWindow.xaml" view:

<Window x:Class="XMLParsingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="XML Parsing Example" Icon="Images\Tiger-icon.png"
        FontFamily="Verdana" FontSize="12">
 
    <Window.DataContext>
        <Binding Source="{StaticResource MainWindowViewModel}" />
    </Window.DataContext>
 
    <Grid Margin="8">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
 
        <Border Grid.Row="0" BorderThickness="1" BorderBrush="Brown"
                CornerRadius="6">
            <TextBlock Margin="15, 5, 5, 5" FontSize="18"
                       FontWeight="SemiBold" Foreground="#666666"
                       Text="XML Parsing Example"></TextBlock>
        </Border>
 
        <Border Grid.Row="1" BorderThickness="1" BorderBrush="Black"
                Margin="0,5,0,0">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                
                <StackPanel Grid.Row="0" Orientation="Horizontal"
                            HorizontalAlignment="Right" Margin="6">
                    <Button Content="Parse XML with XMLDocument"
                            Command="{Binding Path=XMLDocumentLoadCommand}"
                            Margin="0, 0, 5, 0" />
                    <Button Content="Parse XML with XDocument"
                            Command="{Binding Path=XDocumentLoadCommand}"
                            Margin="0, 0, 5, 0" />
                    <Button Content="Clear result"
                            Command="{Binding Path=ClearResultCommand}" />
                </StackPanel>
 
                <Border Grid.Row="1" BorderThickness="1"
                        BorderBrush="Blue" Margin="5">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        
                        <StackPanel Grid.Row="0"
                                    Orientation="Horizontal" Margin="5">
                            <TextBlock FontWeight="SemiBold">School:</TextBlock>
                            <TextBlock Margin="5, 0, 0, 0" Foreground="Green"
                                Text="{Binding Path=StudentInformationObject.School
                                , Mode=OneWay}" />
                            <TextBlock Margin="0, 0, 5, 0">,</TextBlock>
                            <TextBlock FontWeight="SemiBold">Department:</TextBlock>
                            <TextBlock Margin="5, 0, 0, 0" Foreground="Green"
                                Text="{Binding Path=StudentInformationObject.Department
                                , Mode=OneWay}" />
                        </StackPanel>
 
                        <DataGrid Grid.Row="1" Margin="5"
                                  IsReadOnly="True" ColumnHeaderHeight="30"
                              ItemsSource="{Binding Path=
				StudentInformationObject.Studentlist
                            , Mode=OneWay}" />
                    </Grid>
                </Border>
            </Grid>
        </Border> 
    </Grid>
</Window>

There are three "Buttons" in this XAML view. Each button is bound to a corresponding command in the view model. The "Datagrid" is bound to the "Studentlist" of the "StudentInformationObject" property. The view model instance itself is bound to the "DataContext" of this XAML view as a "StaticResource". This instance of the view model class is defined in the "App.xaml" file:

<Application x:Class="XMLParsingExample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:VM="clr-namespace:XMLParsingExample.ViewModels"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <VM:MainWindowViewModel x:Name="MainWindowViewModel" 
		x:Key="MainWindowViewModel" />
    </Application.Resources>
</Application>

Now we finish this demo application, we can start to test run it.

Run the Application

Make the "XMLParsingExample" project the start up project, we can run the application in the debug mode. When the application launches, we can then click on the buttons to test the application. The following picture shows the result when the "Parse XML with XDocument" button is clicked.

RunApplication.JPG

Points of Interest

  • This article demonstrated how to parse XML documents using "XMLDocument" as well as "XDocument".
  • To make this demo a "running" example, I created a WPF MVVM application. If you are only interested in how to parse XML documents, you can skip the introduction of the WPF application. If you are not very familiar with how to create MVVM applications, you can take a look at my earlier article "Data and Command Bindings for Silverlight MVVM Applications".
  • XML and the parsing of XML documents are very old topics now. It should not be common that you will need to directly work on raw XML documents. But when you need to do it, this article is a "running" example on how to parse XML documents using "XMLDocument" as well as "XDocument".
  • In terms of functionality, the "XMLDocument" is very similar to the "linq" flavored "XDocument". It is your own choice which one you want to use. According to this link, "XMLDocument" is not available to Silverlight applications. So if you are working on a Silverlight application, you will need to use the "XDocument".
  • By the time I finished this article, I noticed that there was a typo in the "Student.xml" file. I intended to say "Civil war. Great president!" for president Lincoln, but I wrote it as "Civil was. Great president!". I hope that it won't bother your reading of this article. I will proofread my postings better in the future.
  • I hope you like my postings and I hope this article can help you one way or the other.

History

  • This is the first revision of this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dr. Song Li

United States United States
I have been working in the IT industry for some time. It is still exciting and I am still learning. I am a happy and honest person, and I want to be your friend.

Comments and Discussions

 
GeneralMy vote of 5 Pinmembergizi4-Apr-11 20:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 5 Apr 2011
Article Copyright 2011 by Dr. Song Li
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid