1,知识需求:
(1)访问XML文件的两个基本模型:
一,DOM模型;使用DOM的好处在于它允许编辑和更新XML文档,可以随机访问文档中的数据,可以使用XPath查询,但是,DOM的缺点在于它需要一次性的加载整个文档到内存中,对于大型的文档,这会造成资源问题。
二,流模型;流模型很好的解决了这个问题,因为它对XML文件的访问采用的是流的概念,也就是说,任何时候在内存中只有当前节点,但它也有它的不足,它是只读的,仅向前的,不能在文档中执行向后导航操作。虽然是各有千秋,但我们也可以在程序中两者并用实现优劣互补。C#采用流模型。
流模型每次迭代XML文档中的一个节点,适合于处理较大的文档,所耗内存空间小。流模型中有两种变体——“推”push模型和pull“拉”模型。推模型也就是常说的SAX,SAX是一种靠事件驱动的模型,也就是说:它每发现一个节点就用推模型引发一个事件,而我们必须编写这些事件的处理程序,这样的做法非常的不灵活,也很麻烦。.NET中使用的是基于“拉”模型的实现方案,“拉”模型在遍历文档时会把感兴趣的文档部分从读取器中拉出,不需要引发事件,允许我们以编程的方式访问文档,这大大的提高了灵活性,在性能上“拉”模型可以选择性的处理节点,而SAX每发现一个节点都会通知客户机,从而,使用“拉”模型可以提高Application的整体效率。在.NET中“拉”模型是作为XmlReader类(抽象类)实现的
(2)XmlReader类
Represents a reader that provides
fast, non-cached, forward-only access to XML data.
该类中有三个重要的衍生类:XmlTextReader;XmlTextValidatingReader;XmlNodeReader
(3)XmlNodeType枚举
该枚举里面有很多实用的数。
2,案例(VS2008+XML)
Form1.cs*
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Xml;
namespaceDemoXmlReader
{
public partial class
XmlForm : Form
{
public XmlForm()
{
InitializeComponent();
}
private void btnReaderXML_Click(object sender, EventArgs e)
{
XmlReader xr = new XmlReader(txtPath.Text,lbxml);
try
{
//
xr.EachXmlToListBox();
xr.ReadXmlTextToListBox();
//xr.ReadXml();
}
catch (XmlException xe)
{
MessageBox.Show(xe.ToString(),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString(),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
xr.Dispose();
}
}
private
void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd =
new OpenFileDialog();
ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);
//指定默认打开的窗口指向的文件
ofd.ShowDialog();
txtPath.Text = ofd.FileName;
//把路径复制给txtPath文本框
}
private void btnReaderXmlToCb_Click(object sender, EventArgs e)
{
XmlReader xr = new XmlReader(txtPath.Text, cbxml);
try
{
xr.EachXmlToComboBox();
}
catch (XmlException xe)
{
MessageBox.Show(xe.ToString(),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString(),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
xr.Dispose();
}
}
}
class XmlReader:IDisposable
{
private string xmlPath;
private const string
ERRMSG = "Error ocurred While
Reading";
private ListBox listbox;
private ComboBox combobox;
private XmlTextReader xtr;
#region XmlReader构造器
public XmlReader()
{
this.xmlPath = string.Empty;
this.xtr = null;
this.listbox = null;
}
public XmlReader(string xmlPath,ListBox listbox)
{
this.xmlPath = xmlPath;
this.listbox = listbox;
}
public XmlReader(string xmlPath, ComboBox combobox)
{
this.combobox =
combobox;
this.xmlPath = xmlPath;
}
#endregion
#region XmlReader 资源释放方法
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void
Dispose(bool disposing)
{
if (!disposing)
{
return;
}
if (this.xtr != null)
{
this.xtr.Close();
this.xtr = null;
}
if (this.xmlPath != null)
{
this.xmlPath = null;
}
}
#endregion
#region XmlReader 的属性
public ListBox listBox
{
get { return listbox; }
set{ listbox =value;}
}
public ComboBox comboBox
{
get { return combobox; }
set { combobox = value; }
}
public string XmlPath
{
get { return xmlPath; }
set { xmlPath = value; }
}
#endregion
#region 遍历xml文件
public void EachXmlToListBox()
{
listbox.Items.Clear();
xtr = new XmlTextReader(xmlPath);
try
{
while (xtr.Read())
{
if(xtr.NodeType!=XmlNodeType.XmlDeclaration)
listbox.Items.Add(xtr.Value);
}
}
catch (XmlException xe)
{
throw new XmlException(ERRMSG +
xe.Message);
}
finally {
if (xtr != null)
{
xtr.Close();
}
}
}
public void EachXmlToComboBox()
{
combobox.Items.Clear();
xtr = new XmlTextReader(xmlPath);
try
{
while (xtr.Read())
{
if (xtr.NodeType != XmlNodeType.XmlDeclaration)
combobox.Items.Add(xtr.Value);
}
}
catch (XmlException xe)
{
throw new XmlException(ERRMSG +
xe.Message);
}
finally
{
if (xtr != null)
{
xtr.Close();
}
}
}
#endregion
#region 读取XML文件
public void ReadXml()
{
string attAndEle = string.Empty;
listbox.Items.Clear();
this.xtr = new XmlTextReader(this.xmlPath); //通过路径,读取XML文件
try{
while (xtr.Read()) //按照流方式一个节点一个节点的被动读取。
if the next node was read
successfully,return true
{
//public enum XmlNodeType
为枚举类型,None Element Attribute
Text CDATA EntityReference Entity ProcessingInstruction Comment
Document DocumentType DocumentFragment Notation Whitespace
SignificantWhitespace EndElement EndEntity
XmlDeclaration
if (xtr.NodeType == XmlNodeType.XmlDeclaration) //XmlDeclaration为XML 声明(例如,<?xml
version='1.0'?>)
{
listbox.Items.Add(string.Format("{0}{1}?>",xtr.Name,xtr.Value));
//name为节点名;value为节点内容
}
else if (xtr.NodeType == XmlNodeType.Element) //Element元素(例如,)
{
attAndEle = string.Format("
if (xtr.HasAttributes) //if the current node has attributes,return
true
{
while
(xtr.MoveToNextAttribute()) // if there is a next attribute,return
true
{
attAndEle += string.Format("{0}=''''{1}'''' ", xtr.Name,
xtr.Value);
}
}
attAndEle = attAndEle.Trim() + ">";
listbox.Items.Add(attAndEle);
}
else if (xtr.NodeType == XmlNodeType.EndElement) //An end element tag (for example,
).
{
listbox.Items.Add(string.Format("{0}>",xtr.Name));
}
else if (xtr.NodeType == XmlNodeType.Text) //The text content of a node.
{
listbox.Items.Add(xtr.Value);
}
}
}
catch (XmlException xmlExp)
{
throw new XmlException(ERRMSG + this.xmlPath + xmlExp.ToString());
}
finally
{
if (this.xtr != null)
this.xtr.Close();
}
}
#endregion
#region 读取XML所有文本节点值
public void ReadXmlTextToListBox()
{
listbox.Items.Clear();
xtr = new XmlTextReader(xmlPath);
try
{
while (xtr.Read())
{
if (xtr.NodeType == XmlNodeType.Text)
{
listbox.Items.Add(xtr.Value);
}
}
}
catch (XmlException xe)
{
throw new XmlException(ERRMSG +
xe.Message);
}
finally {
xtr.Close();
}
}
#endregion
}
}