简介 :文档对象模型(DOM)是一种用于处理xml文档的API函数集。

2.1文档对象模型概述

按照W3C的定义,DOM是“一种允许程序或脚本动态地访问更新文档内容,结构和样式的、独立于平台和语言的规范化接口。DOM是表示文档(比如HTML和XML)和访问、操作构成文档的各种元素的应用程序接口,它以树状结构表示HTML和XML文档,定义了遍历这个树和检查、修改树的节点的方法和属性。

DOM的核心API还允许你创建和填充文件、加载文档并保存。

2.2DOM实现

微软的net框架在Systemx.xml命名空间提供了一系列的类用于DOM实现,xmlDocument是NET中Dom实现的核心类之一。正如其他的DOM解析器一样,该类是NET框架的DOC解析器。

xmlDocument将XML文档视为树状结构,他装在xml文档并在内存中构建该文档的树状结构。XmlDocument类代表了一个xml文档、,它支持xml的增删改查;

xmlNode代表一个节点。

 
xml文档组成 部分 对应的类
Document Element(文档元素) XmlElement
Processing Instructions(处理指令) XmlProcessingIntruction
Element(元素)  XmlElement
Attribute(属性) XmlAttribute
Text Values(文本值) XmlText
Nodes(节点) XmlNode

表中所提及的类都直接或者间接的继承了抽象类的XmlNode。

2.3应用实例

2.3.1装载xml文档

XmlDocument类允许你通过三种方式打开一个xml文档:

  1. 指定xml文档路径路程或者URL
  2. 包含xml文档数据的文件流对象
  3. 包含xml文档数据的字符串

接来用这三种方法尝试打开xml文档。代码如下:

 public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void btnopen_Click(object sender, EventArgs e)
{
try
{
XmlDocument doc = new XmlDocument();
if (rdbURL.Checked)
{
doc.Load(txtpath.Text);
}
if (rdbstream.Checked)
{
FileStream stream = new FileStream(txtpath.Text,FileMode.Open);
doc.Load(stream);
stream.Close();
}
if (rdbstring.Checked)
{
doc.LoadXml(txtpath.Text);//加载报错,Loading从指定的字符串中加载xml文档。
doc.LoadXml("<customer ><firstname>Ernestine</firstname><lastname>Borrison</lastname><homephone>(445) 269-7742</homephone><notes>123</notes></customer>");
//
} MessageBox.Show("XML Document Opened Successfully!");
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

xmlDocument类具有俩个重要的方法:Load()和LoadXml()用于加载文档。Load方法通过指定xml文档的文件路径、URL或指向XML文档的流对象来打开XML 文档。

LoadXml方法中则通过指定包含xml文档的字符串来打开xml文档。在这个例子中,LoadXml加载的是文件的路径,导致加载无法成功,讲字符串替换为含有根节点的字符串即可,这个字符串中的节点并不一定是xml文档的根节点,是你选取的这个字符串中的根节点,其他节点应该包含在这个节点的内部,不能含有多个同等级的节点。

2.3.2遍历xml文档

一个xml文档可以包含一个或者对个节点,而每一个节点又可以包含多个子节点,xmlnode类具有一个叫Childnoes的集合体,该集合体包好某种条件下的所有子节点。net框架中与DOM 相关联的其他许多类都直接或者间接的继承自XmlNode类。因而这些类可以调用childNodes集合体。

例子代码:

private void btnload_Click(object sender, EventArgs e)
{
XmlDocument _doc = new XmlDocument();//创建实例
_doc.Load(Application.StartupPath + "/Customers.xml");//加载文件 TreeNode _root = new TreeNode(_doc.DocumentElement.Name);//documentElement 属性可返回文档的根节点
treeView1.Nodes.Add(_root); foreach (XmlNode node in _doc.DocumentElement.ChildNodes)
{
TreeNode _customer = new TreeNode("Customer ID : " + node.Attributes["customerid"].Value);//Attributes表示获取对应的属性信息 _root.Nodes.Add(_customer);
if (node.HasChildNodes)
{
foreach (XmlNode childnode in node.ChildNodes)
{
TreeNode _customer2 = new TreeNode(childnode.Name + " : " + childnode.InnerText);//InnerText获取节点的内部数据 。。。
_customer.Nodes.Add(_customer2);
}
}
}
}

2.3.3查询特殊元素和节点

在实际的使用中我们使用下面这几种方法来查询xml文档树中的 某个或某些元素和节点,去获得相关的信息和数据值。

  1. Ge他ElementByTagName()方法
  2. GetElementById()方法
  3. SelectNodes()方法
  4. SelectSingleNode()方法

1、XmlDcument类的GetElementByTagName()方法以节点的标签名为输入参数。并返回所有具有相同标签名的节点。这些节点包含在一个XmlNodeList类的实例中。

XmlNodeList类代表一个XmlNode对象的集合。代码如下:

 public partial class Form1 : Form
{
#region Constructor
public Form1()
{
InitializeComponent();
}
#endregion #region Variables private XmlNodeList list = null;//代表一个XmlNode对象的集合、
#endregion
private void btnsearch_Click(object sender, EventArgs e)
{
lstresult.Items.Clear(); XmlDocument _doc = new XmlDocument();
_doc.Load(Application.StartupPath + "/customers.xml"); list = _doc.GetElementsByTagName(txttag.Text);//通过标签名获取list foreach (XmlNode node in list)
{
lstresult.Items.Add(node.Name);
}
} private void lstresult_SelectedIndexChanged(object sender, EventArgs e)
{
txtresult.Text = list[lstresult.SelectedIndex].InnerText;
}

2、应用GetElementByld方法

如果xml文档中存在一个具有唯一值的属性,比如人民的身份证这个属性。在查找特殊元素或者节点时,可应用GetElementByld()方法加以实现,其实现方式类似于应用主键在数据库中

查询相应的记录。问题在XmlDocument类不能自动的指定元素的某个特殊的属性作为元素的主键,因此在应用这个方法前,必须在xml文档中通过DTD或者Schema技术指定元素的某个属性作为元素的唯一的“主键”,同时使XmlDocument类能够将该属性视为元素的“主键”。

声明主键的代码如下:

<!DOCTYPE customers[
<!ELEMENT customers ANY>
<!ELEMENT customer ANY>
<!ELEMENT firstname ANY>
<!ELEMENT lastname ANY>
<!ELEMENT homephone ANY>
<!ELEMENT notes ANY>
<!ATTLIST customer customerid ID #REQUIRED>
]>

注意这行代码<!ATTLIST customer customerid ID #REQUIRED>,在此我们将属性customer id 标记为ID并同时规定其实唯一的(#REQUIRED)

这个方法的返回值是包含相应节点数据的XmlElement类的实例对象。

 private void Form1_Load(object sender, EventArgs e)
{
doc = new XmlDocument();
doc.Load(Application.StartupPath+"/Customers.xml");
foreach(XmlNode node in doc.DocumentElement.ChildNodes)
{
string _strid=node.Attributes["customerid"].Value;
cmbID.Items.Add(_strid);
}
} private void cmbID_SelectedIndexChanged(object sender, EventArgs e)
{
XmlElement _xel = doc.GetElementById(cmbID.SelectedItem.ToString());
lblfirst.Text = _xel.ChildNodes[].InnerText;
lbllast.Text = _xel.ChildNodes[].InnerText;
lblphone.Text = _xel.ChildNodes[].InnerText;
lblnote.Text = _xel.ChildNodes[].InnerText;
}

3、应用SelectNodes()方法

在某些情况下,我们需要查询xml文档中付某中或者某些条件的节点。SelectNodes()可以满足这种要求,该方法可以根据查询条件过滤得到符合条件的节点。

返回值一个包含所有有效节点得到XmlNodeList实例对象。

public partial class Form1 : Form
{
#region ariables private XmlNodeList list = null;
#endregion #region Constructor public Form1()
{
InitializeComponent();
}
#endregion
private void btnsearch_Click(object sender, EventArgs e)
{
lstresult.Items.Clear();
XmlDocument _doc = new XmlDocument();
_doc.Load(Application.StartupPath + "/Customers.xml");
if (rdbfirst.Checked)
{
//string str = string.Format("//customer[./firstname/text()='{0}']", txtinput.Text);
//
string str = string.Format("//customer[./homephone[./quhao/text()='{0}']]", txtinput.Text);
//////customer[./firstname/text()='John']
list = _doc.SelectNodes(str);
}
if (rdblast.Checked)
{
list = _doc.SelectNodes(string.Format("//customer[./lastname/text()='{0}']", txtinput.Text));
}
foreach (XmlNode node in list)
{
lstresult.Items.Add(node.Attributes["customerid"].Value);
} } private void btndetail_Click(object sender, EventArgs e)
{
if (lstresult.SelectedIndex < )
{
MessageBox.Show("Please Selected a Customer ID");
}
else
{
lblfirst.Text = list[lstresult.SelectedIndex].ChildNodes[].InnerText;
lbllast.Text = list[lstresult.SelectedIndex].ChildNodes[].InnerText;
lblphone.Text = list[lstresult.SelectedIndex].ChildNodes[].InnerText;
lblnote.Text = list[lstresult.SelectedIndex].ChildNodes[].InnerText;
}
}

4、应用selectSingleNode()方法

该刚方法的不同于selectNodes的是:方法仅返回符合条件的第一个节点。

2.4修改XML文档

对XML文档的修改包括添加或者插入新节点,删除已存在节点、次该节点的相关数据或者属性。DOM 是一个读写型的解释器,因此dom也有提供许多函数方法和类允许你修改文档。

2.4.1 Save方法

save方法保存文件到指定的位置。 该方法传入的参数为XmlWriter、XmlTextWriter或者字符串。

            string filename=@“C:\books.xml”;
XmlDocument xmlDoc= new XmlDocument();
xmlDoc.Load(filename);
XmlTextWriter writer = new XmlTextWriter("c:\\domtest.xml",null);
writer.Formatting=Formatting.Indented;
xmlDoc.Save(writer);
//你也可以使用一个文件名或Console.Out保存文档,或者将文档的内容输出到屏幕上
xmlDoc.Save("c:\\domtest.xml");
xmlDoc.Save(Console.Out);

2.4.2 XmlDocumentFragment类

在xml 文档中插入部分内容或者节点时,用到这个类=》这个类自XmlNode派生。=>通过xml文档的CreateDocumentFragment()方法来创建这个类的实例。

该实例的InnerXml属性代表当前节点的子节点。

XmlDocumentFragment docFrag=xmlDoc.CreateDocumentFragment();

2.4.3 XmlElement类

XmlElement代表文档中的一个元素,这个类继承自XmlLinkedNode,XmlLinkedNode类继承自XmlNode。XmlLinkedNode有俩个属性:NextSibing和PreviousSibling、代表与当前节点处于同一个层次的下一个和以前的节点。

下面网址链接此类的常用方法:网址链接

2.4.4 添加节点到XML 文档中

AppendChild()方法添加节点到文档中,方法接受一个XmlNode类类型的单个参数。xmldocument的creatxxx方法可以创建不同的节点,AppendChild可以将他们加到文档中。

添加评论节点代码:xmlDoc.AppendChild(nodel);

添加元素节点到文档中:xmlDoc.DocumentElement.AppendChild(nodel);

2.4.5 删除和更换节点

XmlNode类的RemoveAll()方法可以删除所有元素和节点的属性、方法RemoveChild()仅用于删除指定的子节点。

代码:XmlNode root= xmlDoc.DocumentElement;root.RemoveALll();

ReplaceChild()方法用于一个新的节点替换旧的节点rootNode.ReplaceChild(xmlDocFragment,rootNode.LastChild);

2.4.6 XML片段插入到xml文档中

XmlNode类提供相应的方法将xml片段插入到xml文档中,例如:InsertAfter()方法在当前节点之后插入一个文档或者元素。

该方法需要俩个参数,1:XmlDocumentFragment对象,2:要在其中插入片段的位置。(插入位置)

aNode.InsertAfter(xmlDocFragment,aNode.LastChild);

2.4.7添加属性到节点中

使用XmlElement类的SetAttributeNode()方法添加节点的属性。

   XmlElement newElem=xmlDoc.CreateElement("NewElement");
//创建指定名称的元素
XmlAttribute newAttr=xmlDoc.CreateAttribute("NewAttribute");
newElem.SetAttributeNode(newAttr);

2.5综合实例

 public partial class Form1 : Form
{
#region Variables private XmlDocument doc;
private int nodeindex = ; private bool isadd = false;
#endregion #region Constructor public Form1()
{
InitializeComponent(); }
#endregion #region Methods private void AddItemsIntoCombBox(XmlDocument _doc)
{
cmbID.Items.Clear();
foreach (XmlNode _node in _doc.DocumentElement.ChildNodes)
{
cmbID.Items.Add(_node.Attributes["customerid"].Value);
}
}
private void NodeRemoved(object sender, XmlNodeChangedEventArgs e)
{
MessageBox.Show("Node " + e.Node.Name + " removed successfully!");
} private void NodeInserted(object sender, XmlNodeChangedEventArgs e)
{
if (isadd)
{
MessageBox.Show("Node " + e.Node.Name + " added successfully!");
}
isadd = false;
} private void NodeChanged(object sender, XmlNodeChangedEventArgs e)
{
MessageBox.Show("Node " + e.Node.Name + " changed successfully!");
}
private void FillControlters()
{
XmlNode _nod = doc.DocumentElement.ChildNodes[nodeindex];
cmbID.Text = _nod.Attributes["customerid"].Value;
txtfname.Text = _nod.ChildNodes[].InnerText;
txtlname.Text = _nod.ChildNodes[].InnerText;
txtphone.Text = _nod.ChildNodes[].InnerText;
txtnote.Text = _nod.ChildNodes[].InnerText; this.UpdateInformation();
}
private void UpdateInformation()
{
lblinformation.Text = "Customer " + (nodeindex + ) + " of " + doc.DocumentElement.ChildNodes.Count.ToString();
}
#endregion private void Form1_Load(object sender, EventArgs e)
{
doc = new XmlDocument();
doc.Load(Application.StartupPath + "/customers.xml"); this.AddItemsIntoCombBox(doc); this.FillControlters(); doc.NodeChanged += new XmlNodeChangedEventHandler(NodeChanged);
doc.NodeInserted += new XmlNodeChangedEventHandler(NodeInserted);
doc.NodeRemoved += new XmlNodeChangedEventHandler(NodeRemoved); } private void btnadd_Click(object sender, EventArgs e)
{
if ((txtfname.Text == "") || (txtlname.Text == "") || (txtphone.Text == "") || (txtnote.Text == ""))
{
MessageBox.Show("Please fill up all items of customer!");
return;
}
XmlElement _customer = doc.CreateElement("customer");
XmlElement _firstname = doc.CreateElement("firstname");
XmlElement _lastname = doc.CreateElement("lastname");
XmlElement _homephone = doc.CreateElement("homephone");
XmlElement _notes = doc.CreateElement("notes"); XmlAttribute _customerid = doc.CreateAttribute("customerid");
_customerid.Value = cmbID.Text; XmlText _firstnametext = doc.CreateTextNode(txtfname.Text);
XmlText _lastnametext = doc.CreateTextNode(txtlname.Text);
XmlText _homephonetext = doc.CreateTextNode(txtphone.Text);
XmlCDataSection _notestext = doc.CreateCDataSection(txtnote.Text); _customer.Attributes.Append(_customerid);
_customer.AppendChild(_firstname);
_customer.AppendChild(_lastname);
_customer.AppendChild(_homephone);
_customer.AppendChild(_notes); _firstname.AppendChild(_firstnametext);
_lastname.AppendChild(_lastnametext);
_homephone.AppendChild(_homephonetext);
_notes.AppendChild(_notestext); isadd = true; doc.DocumentElement.AppendChild(_customer);
doc.Save(Application.StartupPath + "/Customers.xml"); this.AddItemsIntoCombBox(doc); this.UpdateInformation();
} private void btnupdate_Click(object sender, EventArgs e)
{
if ((txtfname.Text == "") || (txtlname.Text == "") || (txtphone.Text == "") || (txtnote.Text == ""))
{
MessageBox.Show("Please fill up all items of customer!");
return;
}
XmlNode _node = doc.SelectSingleNode("//customer[@customerid='" + cmbID.SelectedItem + "']");
if (_node != null)
{
if (_node.ChildNodes[].InnerText != txtfname.Text)
_node.ChildNodes[].InnerText = txtfname.Text;
if (_node.ChildNodes[].InnerText != txtlname.Text)
_node.ChildNodes[].InnerText = txtlname.Text;
if (_node.ChildNodes[].InnerText != txtphone.Text)
_node.ChildNodes[].InnerText = txtphone.Text;
if (_node.ChildNodes[].InnerText != txtnote.Text)
{
XmlCDataSection _notes = doc.CreateCDataSection(txtnote.Text);
isadd = true;
_node.ChildNodes[].ReplaceChild(_notes, _node.ChildNodes[].ChildNodes[]);
}
}
doc.Save(Application.StartupPath + "/Customers.xml");
} private void btndelete_Click(object sender, EventArgs e)
{
XmlNode _node = doc.SelectSingleNode("//customer[@customerid='" + cmbID.SelectedItem + "']");
if (_node != null)
{
doc.DocumentElement.RemoveChild(_node);
}
doc.Save(Application.StartupPath + "/Customers.xml"); nodeindex = ;
this.FillControlters();
this.UpdateInformation();
this.AddItemsIntoCombBox(doc);
} private void btnfirst_Click(object sender, EventArgs e)
{
nodeindex = ;
this.FillControlters();
} private void btnprevious_Click(object sender, EventArgs e)
{
nodeindex--;
if (nodeindex < )
{
nodeindex = ;
}
this.FillControlters();
} private void btnnext_Click(object sender, EventArgs e)
{
nodeindex++;
if (nodeindex >= doc.DocumentElement.ChildNodes.Count)
{
nodeindex = doc.DocumentElement.ChildNodes.Count - ;
}
this.FillControlters();
} private void btnlast_Click(object sender, EventArgs e)
{
nodeindex = doc.DocumentElement.ChildNodes.Count - ;
this.FillControlters();
}

2.6处理空白

加载文档时,默认情况下,XMLDocument类忽略空白。通过设置PreserveWhiteSpace的布尔型属性来控制是否需要空白内容,true将保存空白内容,false将不保留空白内容。

2.7XmlDocument类的事件

当修改xml 文档时,会激发小毛驴document类提供的事件过程,这些事件过程分别遵循事前或者事后激发模式。

NodeChanged

当属于该文档的节点的 Value 已被更改时发生。

NodeChanging

当属于该文档的节点的 Value 将被更改时发生。

NodeInserted

当属于该文档的节点已被插入另一个节点时发生。

NodeInserting

当属于该文档的节点将被插入另一个节点时发生。

NodeRemoved

Occurs when a node belonging to this document has been removed from its parent.

NodeRemoving

当属于该文档的节点将从文档中移除时发生。

表中的事件都接受一个XmlNodeChangeEventArgs类型的参数

下面提供这个类型参数的一些属性

Action

获取一个值,该值指示正在发生哪种类型的节点更改事件。

NewParent

获取操作完成后 ParentNode 的值。

NewValue

获取节点的新值。

Node

获取正被添加、移除或更改的 XmlNode

OldParent

获取操作开始前的 ParentNode 的值。

OldValue

获取节点的原始值。

文档对象模型操作xml文档的更多相关文章

  1. 操作xml文档的常用方式

    1.操作XML文档的两种常用方式: 1)使用XmlReader类和XmlWriter类操作 XmlReader是基于数据流的,占用极少的内存,是只读方式的,所以速度极快.只能采用遍历的模式查找数据节点 ...

  2. 操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP)

    原文:操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP) 不管是用 PHP 还是 C#, 在操作 XML 的时候我们除了一个节点一个节点去取值之外, 还有一个非常方便的表达式, 就是 ...

  3. 用ORM的思想操作XML文档,一个对象就搞定不要太简单。滚蛋吧!XmlDocument、XmlNode、Xml***……

    大家有没有这样的感受,一涉及XML文档操作就得百度一遍.是不是非!常!烦!.各种类型,各种方法,更别提为了找到一个节点多费劲.本来想写个XML操作的工具方法,写了两行一想既然XML文档是有规律的,如果 ...

  4. C#操作XML文档---基础

    增查改删代码如下 public void CreateXML() { XmlDocument xml = new XmlDocument(); xml.AppendChild(xml.CreateXm ...

  5. C#XmlHelper操作Xml文档的帮助类

    using System.Xml; using System.Data; namespace DotNet.Utilities { /// <summary> /// Xml的操作公共类 ...

  6. [XML] C# XmlHelper操作Xml文档的帮助类 (转载)

    点击下载 XmlHelper.rar 主要功能如下所示 /// <summary> /// 类说明:XmlHelper /// 编 码 人:苏飞 /// 联系方式:361983679 // ...

  7. C#操作XML文档(XmlDocument、XmlNode、XmlAttribute、SelectSingleNode、SelectNodes、XmlNodeList)

    XML文档是一种通用的文档,这种文档既可以用.config作为后缀也可以用.xml作为后缀.XML文档主要由元素节点和节点的属性共同构成的.它有且仅有一个根节点,其他的节点全部都是根节点的子节点或者子 ...

  8. dom4j操作xml文档

    java Dom4j解析XML文件 标签(空格分隔):java进阶 xml文档: <?xml version="1.0" encoding="UTF-8" ...

  9. C# 操作XML文档 使用XmlDocument类方法

    W3C制定了XML DOM标准.很多编程语言中多提供了支持W3C XML DOM标准的API.我在之前的文章中介绍过如何使用Javascript对XML文档进行加载与查询.在本文中,我来介绍一下.Ne ...

随机推荐

  1. UFLDL教程(五)之self-taught learning

    这里所谓的自学习,其实就是利用稀疏自编码器对无标签样本学习其特征 该自学习程序包括两部分: 稀疏自编码器学习图像特征(实现自学习)---用到无标签的样本集 softmax回归对样本分类---用到有标签 ...

  2. Python 处理EXCEL的CSV文档分列求SUM

    相对于导出EXCEL文件,PYTHON计算更为实时. import csv import sys from optparse import OptionParser def calculate_pro ...

  3. java-String中的 intern()<转>

    1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ne ...

  4. keil多文件组织方法

    方法一 首先新建一个main.c的文件,加入到项目中,该文件中主要写main函数,然后,新建文件,如delay.c,编写内容之后,不要加入到项目,而是在main.c文件的开始写上#include“de ...

  5. android中保存一个ArrayList到SharedPreferences的方法

    保存: public static boolean saveArray() { SharedPrefernces sp=SharedPrefernces.getDefaultSharedPrefern ...

  6. Git简明手册

    文/AbnerKang(简书作者)原 文链接:http://www.jianshu.com/p/d7a7ba4f2341?utm_campaign=maleskine& utm_content ...

  7. vs默认的app.config是哪个?

    一:这次是进一步的三层构架,不过还是没有业务逻辑层,但有单独的层的文件夹,解决方案资源管理器图如下: 二:operatorDAl.cs代码: using System; using System.Co ...

  8. HDU-4972 A simple dynamic programming problem

    http://acm.hdu.edu.cn/showproblem.php?pid=4972 ++和+1还是有区别的,不可大意. A simple dynamic programming proble ...

  9. leetcode shttps://oj.leetcode.com/problems/surrounded-regions/

    1.从外围搜索O,深度搜索出现了 Line 35: java.lang.StackOverflowError Last executed input: ["OOOOOOOOOOOOOOOOO ...

  10. jboss as7 o.h.c.s.c.i.BroadcastGroupImpl Network is unreachable

    Question: [Server:server-one] 22:52:56,876 ERROR [org.hornetq.core.server.cluster.impl.BroadcastGrou ...