读取XML到ListBox/ComboBox1,知识需求:(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.该类中有三个重要的衍生类:XmlT extReader;XmlT extValidatingReader;XmlNodeReader (3)XmlNodeType枚举该枚举里面有很多实用的数。
2,案例(VS2008+XML)Form1.cs*using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Xml;namespace DemoXmlReader{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) {bobox = 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 readsuccessfully,return true{//public enum XmlNodeType 为枚举类型,None Element Attribute Text CDATA EntityReference Entity ProcessingInstruction Comment Document DocumentType DocumentFragment Notation Whitespace SignificantWhitespace EndElement EndEntity XmlDeclarationif (xtr.NodeType == XmlNodeType.XmlDeclaration) //XmlDeclaration为XML 声明(例如,<?xml version='1.0'?>){listbox.Items.Add(string.Format("<?{0}{1}?>",,xtr.Value)); //name为节点名;value 为节点内容}else if (xtr.NodeType == XmlNodeType.Element) //Element元素(例如,<item>){attAndEle = string.Format("<{0}",);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.Value);}}attAndEle = attAndEle.Trim() + ">";listbox.Items.Add(attAndEle);}else if (xtr.NodeType == XmlNodeType.EndElement) //An end element tag (for example, </item> ). {listbox.Items.Add(string.Format("</{0}>",));}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}}。