使用 XMLDocument 和 XDocument 解析 XML 文档
本文演示如何使用 "XMLDocument" 和 "XDocument" 解析 XML 文档。
引言
本文演示如何使用 "XMLDocument" 和 "XDocument" 解析 XML 文档。
背景
"XML" 和 XML 文档的解析是旧话题,我们不常直接处理 XML 文档。但偶尔,您可能会遇到需要解析一些原始 XML 文档的情况。本文旨在演示如何使用两个常用的 .NET 实用类 "XMLDocument" 和 "XDocument" 来解析 XML 文档。

随附的 Visual Studio 2010 解决方案包含两个项目
- "
XMLWebRepository
" 项目是一个 ASP.NET Web 项目。此项目中的 "Student.xml" 文件是演示中使用的 XML 文件。 - "
XMLParsingExample
" 项目是一个简单的 WPF "MVVM" 应用程序。我们将使用此应用程序演示如何使用 "XMLDocument" 和 "XDocument" 解析 XML 文档。
让我们首先看一下 "XMLWebRepository
" 项目和 XML 文档 "Student.xml"。
要解析的 XML 文档
此演示中使用的 XML 文档位于 "XMLWebRepository
" 项目中的 "Student.xml" 文件中
<?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>
如果您在解决方案资源管理器中右键单击 "Student.xml" 文件并选择 "在浏览器中查看",则会显示一个网页浏览器,如下所示

您应该注意地址栏中的 URL "https://:7467/Student.xml"。这是 "XMLParsingExample
" 项目将用于加载 XML 文档的 URL。现在让我们看一下 "XMLParsingExample
" 项目,了解我们将如何使用 "XMLDocument" 和 "XDocument" 解析 "Student.xml"。
解析 XML 文档
在 "XMLParsingExample
" 项目中,为了保存解析 "Student.xml" 的结果,在 "Models" 文件夹中的 "ApplicationModel.cs" 文件中创建了两个类
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>();
}
}
}
您可能已经注意到这两个类与 "Student.xml" 文件中的信息直接相关。我们将读取 "Student.xml" 文件中的信息并将其保存到 "StudentsInformation
" 类的对象中。演示如何解析 XML 文档的代码在 "Models" 文件夹中的 "XMLParsers.cs" 文件中实现
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 = "https://: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;
}
}
}
静态类 "XMLParsers
" 实现了两个静态
方法
- "
ParseByXMLDocument
" 方法演示如何使用 "XMLDocument" 解析 XML 文档。 - "
ParseByXDocument
" 方法演示如何使用 "XDocument" 解析 XML 文档。
这两个方法非常相似,但是 "LINQ" 风格的 "XDocument" 使我们能够节省几行 C# 代码。这两个方法都非常简单,您阅读它们应该不会有太多问题。如果您只对如何解析 XML 文档感兴趣,可以跳过本文的其余部分。但是为了使此演示成为一个“运行”示例,我将对 "XMLParsingExample
" 项目进行简要的总体介绍。
"XMLParsingExample" 应用程序
"XMLParsingExample
" 项目是一个 WPF MVVM 应用程序。我有一篇专门的文章 "Silverlight MVVM 应用程序的数据和命令绑定" 来讨论如何在 MVVM 应用程序中实现数据和命令绑定。如果您感兴趣,可以查看它,这将使您阅读本文的其余部分更容易。为了帮助实现 "XMLParsingExample
" 应用程序,我在 "MVVMUtilities" 文件夹中的 "BindingUtilities.cs" 文件中实现了两个实用类
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();
}
}
}
"ViewModelBase
" 类将是 MVVM 应用程序中所有视图模型的基类,"RelayCommand
" 类将用于在视图模型中实现 "命令"。 "XMLParsingExample
" 应用程序的简单视图模型在 "ViewModels" 文件夹中的 "MainWindowViewModel.cs" 文件中实现
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();
}
}
}
此视图模型类实现了一个公共
属性和三个命令
- "
StudentInformationObject
" 属性用于保存解析 "Student.xml" 文件获得的信息。 - "
XMLDocumentLoadCommand
" 命令通过调用 "XMLParsers
" 类中的 "ParseByXMLDocument
" 方法,使用 "XMLDocument" 解析 "Student.xml" 文件。 - "
XDocumentLoadCommand
" 命令通过调用 "XMLParsers
" 类中的 "ParseByXDocument
" 方法,使用 "XDocument" 解析 "Student.xml" 文件。 - "
ClearResultCommand
" 命令清除 "StudentInformationObject
" 属性。
此视图模型绑定到 "MainWindow.xaml" 视图
<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>
此 XAML 视图中有三个 "按钮"。每个按钮都绑定到视图模型中相应的命令。数据网格绑定到 "StudentInformationObject
" 属性的 "Studentlist
"。视图模型实例本身绑定到此 XAML 视图的 "DataContext" 作为 "StaticResource"。视图模型类的此实例在 "App.xaml" 文件中定义
<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>
现在我们完成了这个演示应用程序,我们可以开始测试运行它。
运行应用程序
将 "XMLParsingExample
" 项目设置为启动项目,我们可以在调试模式下运行应用程序。应用程序启动后,我们可以单击按钮来测试应用程序。下图显示了单击 "使用 XDocument 解析 XML" 按钮时的结果。

关注点
- 本文演示了如何使用 "XMLDocument" 和 "XDocument" 解析 XML 文档。
- 为了使此演示成为一个“运行”示例,我创建了一个 WPF MVVM 应用程序。如果您只对如何解析 XML 文档感兴趣,可以跳过 WPF 应用程序的介绍。如果您不太熟悉如何创建 MVVM 应用程序,可以查看我的早期文章 "Silverlight MVVM 应用程序的数据和命令绑定"。
- XML 和 XML 文档的解析现在是非常老的话题。您应该不常需要直接处理原始 XML 文档。但是当您需要这样做时,本文提供了一个“运行”示例,说明如何使用 "XMLDocument" 和 "XDocument" 解析 XML 文档。
- 在功能方面,"XMLDocument" 与 "LINQ" 风格的 "XDocument" 非常相似。选择哪一个由您自己决定。根据此链接,"XMLDocument" 不适用于 Silverlight 应用程序。因此,如果您正在使用 Silverlight 应用程序,则需要使用 "XDocument"。
- 在我完成这篇文章时,我注意到 "Student.xml" 文件中有一个错字。我本想对林肯总统说“内战。伟大的总统!”(Civil war. Great president!),但我写成了“内战。(Civil was.) 伟大的总统!”。我希望这不会影响您阅读本文。我将来会更好地校对我的帖子。
- 我希望您喜欢我的文章,希望本文能以某种方式帮助您。
历史
- 这是本文的第一个修订版。