C#中常用的几种读取XML文件的方法

C#中常用的几种读取XML文件的方法,第1张

Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。微软也提供了一系列类库来倒帮助我们在应用程序中存储XML文件。> 2: 3: 4: 5:数据结构 6:严蔚敏 7:3000 8: 9: 10:路由型与交换型互联网基础 11:程庆梅 12:2700 13: 14: 15:计算机硬件技术基础 16:李继灿 17:2500 18: 19: 20:软件质量保证与管理 21:朱少民 22:3900 23: 24: 25:算法设计与分析 26:王红梅 27:2300 28: 29: 30:计算机 *** 作系统 31:7-111-19149-1 32:28 33: 34:为了方便读取,我还定义一个书的实体类,名为BookModel,具体内容如下: 1:using System; 2:using SystemCollectionsGeneric; 3:using SystemLinq; 4:using SystemText; 5: 6:namespace 使用XmlDocument 7: { 8:publicclass BookModel 9: { 10:public BookModel() 11: { } 12:/// 13:/// 所对应的课程类型 14:/// 15:privatestring bookType; 16: 17:publicstring BookType 18: { 19: get { return bookType; } 20: set { bookType = value; } 21: } 22: 23:/// 24:/// 书所对应的ISBN号 25:/// 26:privatestring bookISBN; 27: 28:publicstring BookISBN 29: { 30: get { return bookISBN; } 31: set { bookISBN = value; } 32: } 33: 34:/// 35:/// 书名 36:/// 37:privatestring bookName; 38: 39:publicstring BookName 40: { 41: get { return bookName; } 42: set { bookName = value; } 43: } 44: 45:/// 46:/// 作者 47:/// 48:privatestring bookAuthor; 49: 50:publicstring BookAuthor 51: { 52: get { return bookAuthor; } 53: set { bookAuthor = value; } 54: } 55: 56:/// 57:/// 价格 58:/// 59:privatedouble bookPrice; 60: 61:publicdouble BookPrice 62: { 63: get { return bookPrice; } 64: set { bookPrice = value; } 65: } 66: } 67: }1使用XmlDocument使用XmlDocument是一种基于文档结构模型的方式来读取XML文件在XML文件中,我们可以把XML看作是由文档声明(Declare),元素(Element),属性(Attribute),文本(Text)等构成的一个树最开始的一个结点叫作根结点,每个结点都可以有自己的子结点得到一个结点后,可以通过一系列属性或方法得到这个结点的值或其它的一些属性例如: 1: xn 代表一个结点 2: xnName;//这个结点的名称 3: xnValue;//这个结点的值 4: xnChildNodes;//这个结点的所有子结点 5: xnParentNode;//这个结点的父结点 6: 11 读取所有的数据使用的时候,首先声明一个XmlDocument对象,然后调用Load方法,从指定的路径加载XML文件 1: XmlDocument doc = new XmlDocument(); 2: docLoad(@"\\Bookxml");然后可以通过调用SelectSingleNode得到指定的结点,通过GetAttribute得到具体的属性值参看下面的代码 1:// 得到根节点bookstore 2: XmlNode xn = xmlDocSelectSingleNode("bookstore"); 3: 4: 5:// 得到根节点的所有子节点 6: XmlNodeList xnl = xnChildNodes; 7: 8:foreach (XmlNode xn1 in xnl) 9: { 10: BookModel bookModel = new BookModel(); 11:// 将节点转换为元素,便于得到节点的属性值 12: XmlElement xe = (XmlElement)xn1; 13:// 得到Type和ISBN两个属性的属性值 14: bookModelBookISBN = xeGetAttribute("ISBN")ToString(); 15: bookModelBookType = xeGetAttribute("Type")ToString(); 16:// 得到Book节点的所有子节点 17: XmlNodeList xnl0 = xeChildNodes; 18: bookModelBookName=xnl0Item(0)InnerText; 19: bookModelBookAuthor=xnl0Item(1)InnerText; 20: bookModelBookPrice=ConvertToDouble(xnl0Item(2)InnerText); 21: bookModeListAdd(bookModel); 22: } 23: dgvBookInfoDataSource = bookModeList;在正常情况下,上面的代码好像没有什么问题,但是对于读取上面的XML文件,则会出错,原因就是因为我上面的XML文件里面有注释,大家可以参看Bookxml文件中的第三行,我随便加的一句注释注释也是一种结点类型,在没有特别说明的情况下,会默认它也是一个结点(Node)所以在把结点转换成元素的时候就会报错"无法将类型为“SystemXmlXmlComment”的对象强制转换为类型“SystemXmlXmlElement”。"幸亏它里面自带了解决办法,那就是在读取的时候,告诉编译器让它忽略掉里面的注释信息修改如下: 1: XmlDocument xmlDoc = new XmlDocument(); 2: XmlReaderSettings settings = new XmlReaderSettings(); 3: settingsIgnoreComments = true;//忽略文档里面的注释 4: XmlReader reader = XmlReaderCreate(@"\\Bookxml", settings); 5: xmlDocLoad(reader);最后读取完毕后,记得要关掉reader 1: readerClose();这样它就不会出现错误最后运行结果如下:12 增加一本书的信息向文件中添加新的数据的时候,首先也是通过XmlDocument加载整个文档,然后通过调用SelectSingleNode方法获得根结点,通过CreateElement方法创建元素,用CreateAttribute创建属性,用AppendChild把当前结点挂接在其它结点上,用SetAttributeNode设置结点的属性具体代码如下:加载文件并选出要结点: 1: XmlDocument doc = new XmlDocument(); 2: docLoad(@"\\Bookxml"); 3: XmlNode root = docSelectSingleNode("bookstore");创建一个结点,并设置结点的属性: 1: XmlElement xelKey = docCreateElement("book"); 2: XmlAttribute xelType = docCreateAttribute("Type"); 3: xelTypeInnerText = "adfdsf"; 4: xelKeySetAttributeNode(xelType);创建子结点: 1: XmlElement xelAuthor = docCreateElement("author"); 2: xelAuthorInnerText = "dfdsa"; 3: xelKeyAppendChild(xelAuthor);最后把book结点挂接在要结点上,并保存整个文件: 1: rootAppendChild(xelKey); 2: docSave(@"\\Bookxml");用上面的方法,是向已有的文件上追加数据,如果想覆盖原有的所有数据,可以更改一下,使用LoadXml方法: 1: XmlDocument doc = new XmlDocument(); 2: docLoadXml("");//用这句话,会把以前的数据全部覆盖掉,只有你增加的数据直接把根结点选择出来了,后面不用SelectSingleNode方法选择根结点,直接创建结点即可,代码同上13 删除某一个数据想要删除某一个结点,直接找到其父结点,然后调用RemoveChild方法即可,现在关键的问题是如何找到这个结点,上面的SelectSingleNode可以传入一个Xpath表,我们通过书的ISBN号来找到这本书所在的结点如下: 1: XmlElement xe = xmlDocDocumentElement; // DocumentElement 获取xml文档对象的根XmlElement 2:string strPath = stringFormat("/bookstore/book[@ISBN=\"{0}\"]", dgvBookInfoCurrentRowCells[1]ValueToString()); 3: XmlElement selectXe = (XmlElement)xeSelectSingleNode(strPath); //selectSingleNode 根据XPath表达式,获得符合条件的第一个节点 4: selectXeParentNodeRemoveChild(selectXe);"/bookstore/book[@ISBN=\"{0}\"]"是一个Xpath表达式,找到ISBN号为所选那一行ISBN号的那本书,有关Xpath的知识请参考:XPath 语法14 修改某要条数据修改某 条数据的话,首先也是用Xpath表达式找到所需要修改的那一个结点,然后如果是元素的话,就直接对这个元素赋值,如果是属性的话,就用SetAttribute方法设置即可如下: 1: XmlElement xe = xmlDocDocumentElement; // DocumentElement 获取xml文档对象的根XmlElement 2:string strPath = stringFormat("/bookstore/book[@ISBN=\"{0}\"]", dgvBookInfoCurrentRowCells[1]ValueToString()); 3: XmlElement selectXe = (XmlElement)xeSelectSingleNode(strPath); //selectSingleNode 根据XPath表达式,获得符合条件的第一个节点 4: selectXeSetAttribute("Type", dgvBookInfoCurrentRowCells[0]ValueToString());//也可以通过SetAttribute来增加一个属性 5: selectXeGetElementsByTagName("title")Item(0)InnerText = dgvBookInfoCurrentRowCells[2]ValueToString(); 6: selectXeGetElementsByTagName("author")Item(0)InnerText = dgvBookInfoCurrentRowCells[3]ValueToString(); 7: selectXeGetElementsByTagName("price")Item(0)InnerText = dgvBookInfoCurrentRowCells[4]ValueToString(); 8: xmlDocSave(@"\\Bookxml");2使用XmlTextReader和XmlTextWriterXmlTextReader和XmlTextWriter是以流的形式来读写XML文件21XmlTextReader使用XmlTextReader读取数据的时候,首先创建一个流,然后用read()方法来不断的向下读,根据读取的结点的类型来进行相应的 *** 作如下: 1: XmlTextReader reader = new XmlTextReader(@"\\Bookxml"); 2: List modelList = new List(); 3: BookModel model = new BookModel(); 4:while (readerRead()) 5: { 6: 7:if (readerNodeType == XmlNodeTypeElement) 8: { 9:if (readerName == "book") 10: { 11: modelBookType = readerGetAttribute(0); 12: modelBookISBN = readerGetAttribute(1); 13: } 14:if (readerName == "title") 15: { 16: modelBookName=readerReadElementString()Trim(); 17: } 18:if (readerName == "author") 19: { 20: modelBookAuthor = readerReadElementString()Trim(); 21: } 22:if (readerName == "price") 23: { 24: modelBookPrice = ConvertToDouble(readerReadElementString()Trim()); 25: } 26: } 27: 28:if (readerNodeType == XmlNodeTypeEndElement) 29: { 30: modelListAdd(model); 31: model = new BookModel(); 32: } 33: 34: 35: } 36: modelListRemoveAt(modelListCount-1); 37:thisdgvBookInfoDataSource = modelList;关键是读取属性的时候,你要先知道哪一个结点具有几个属性,然后通过GetAttribute方法来读取读取属性还可以用另外一种方法,就是用MoveToAttribute方法可参见下面的代码: 1:if (readerName == "book") 2: { 3:for (int i = 0; i < readerAttributeCount; i++) 4: { 5: readerMoveToAttribute(i); 6:string str = "属性:" + readerName + "=" + readerValue; 7: } 8: modelBookType = readerGetAttribute(0); 9: modelBookISBN = readerGetAttribute(1); 10: }效果如下:22XmlTextWriterXmlTextWriter写文件的时候,默认是覆盖以前的文件,如果此文件名不存在,它将创建此文件首先设置一下,你要创建的XML文件格式, 1: XmlTextWriter myXmlTextWriter = new XmlTextWriter(@"\\Book1xml", null); 2://使用 Formatting 属性指定希望将 XML 设定为何种格式。

XML(eXtensible Markup Language可扩展标志语言)在近几年的信息类杂志 网站上可谓是最抢眼的一词 大大小小的信息产品都争相和它搭上关系 唯恐赶不及这辆快车 有着良好口碑的宝蓝(Borland)系列开发平台也不例外 从 版开始就集成了XML组件包 因其使用MSXMLDom解析器 相比于此前广泛应用的XMLParser解析器 MSXMLDom更显规范 中文兼容性更好(元素名 属性名均支持中文) 很受开发者青睐 为帮助初学者快速掌握Delphi中的XML编程 笔者特写此文 以供交流

笔者通过一个读写XML文件的实例来说明XML编程的各个步骤 只需读者有结点 元素 属性的基本概念就能容易的理解本文 笔者所要读入的XML文件结构如下所示 命名为Input xml

<学生花名册>

<学生 性别 = 男 >

<姓名>李华

<年龄>

<电话>

<学生 性别 = 男 >

<姓名>张三

<年龄>

<电话>

Input xml文件的第一行是XML的版本说明 属性encoding宣告使用何种字符集建立 默认以Unicode 编码(UTF 或UTF ) 这里用中文GB 码 第二行 <学生花名册> 是根元素 下面定义了两个学生元素 学生下面嵌套了三个子元素 是对学生的进一步说明 与之相对应的 我们在Delphi中定义如下的学生数据结构 // 后面的文字是对变量或语句的说明 下同

TStudent = class {学生}

sex : string; //学生性别

name : string; //学生姓名

age : integer; //学生年龄

phone: string; //电话号码

end;

为了读写 我们需要放置两个TXMLDocument控件 在Delphi VCL面板的Internet标签页里那个标有XML字样的控件就是 当然此控件也可以动态创建 但需要包含必要的文件 这里为简单起见 我们直接放置在窗体上 分别命名为InXMLDoc和OutXMLDoc InXMLDoc用于调入Input xml文件 OutXMLDoc用于暂存输出到Output xml的文档

在窗体上放个按钮 我们把测试代码直接放置在按钮的单击事件里 先定义几个变量 用来保存临时信息 如下所示

Root : IXMLNode; //指向XML根结点

Parent_Node: IXMLNode; //指向学生结点

Child_node : IXMLNode; //指向学生的子结点

Student : TStudent; //存单个学生信息

List : TList; //存学生列表

i : integer; //循环变量

我们先来读入XML文件 代码如下

List := TList Create; //初始化列表

InXMLDoc LoadFromFile( Input xml ); //调入Input xml文件

Root := InXMLDoc DocumentElement; //取XML文件的根结点 即 <学生花名册>

Parent_Node := Root ChildNodes First; //使Parent_Node指向学生结点

while (Parent_Node <> nil) do //循环取多个学生 可再多加几个学生信息测试

begin

if (Parent_Node NodeName = 学生 ) then //判断是否为学生结点

begin

Student := TStudent Create; //新建一个学生的结构信息

Student sex := Parent_Node Attributes[ 性别 ]; //取学生的性别属性

Child_Node := Parent_Node ChildNodes First;

//使Child_Node指向该学生的第一个子结点信息

while (Child_Node <> nil) do //循环取学生的各个子各点

begin

if (Child_Node NodeName = 姓名 ) then //判断是否为姓名结点

Student name := Child_Node Text //取姓名结点的值 取于name字段中

else if (Child_Node NodeName = 年龄 ) then //此行起后四行与前两行类似

Student age := StrToInt(Child_Node Text)

else if (Child_Node NodeName = 电话 ) then

Student phone := Child_Node Text;

Child_Node := Child_Node NextSibling; //顺序取下一个学生的子结点信息

end;

List Add(Student); //把一个学生信息加入列表

end;

Parent_Node := Parent_Node NextSibling; //顺序取下一个学生信息

end;

到这儿 所有的学生信息都已存到List列表里面了 读者可以跟踪代码测试

下面我们把List里的临时学生信息存到Output xml文件里 代码如下

OutXMLDoc Active := true; //激活OutXMLDoc 自动初始化空的XML文档

OutXMLDoc Encoding := GB ; //设置字符集

Root := OutXMLDoc AddChild( 学生花名册 ); //建根结点

for i := to List Count do //循环取各个学生信息

begin

Student := List Items[i]; //顺序取一个学生信息

if (Student <> nil) then

begin

Parent_Node := Root AddChild( 学生 ); //根结点后添加一个学生结点

Parent_Node Attributes[ 性别 ] := Student sex; //给学生结点设置性别属性

Child_Node := Parent_Node AddChild( 姓名 ); //学生结点后添加一个姓名结点

Child_Node Text := Student name; //设置姓名的文本值

Child_Node := Parent_Node AddChild( 年龄 ); //此行起后四行与前两行类似

Child_Node Text := IntToStr(Student age);

Child_Node := Parent_Node AddChild( 电话 );

Child_Node Text := Student phone;

end;

end;

OutXMLDoc SaveToFile( Output xml ); //把组织好的XML文档存于Output xml文件中

OutXMLDoc Active := false; //钝化(关闭)OutXMLDoc

List Free; //最后释放保存临时学生信息的列表

lishixinzhi/Article/program/Delphi/201311/24984

;   ——此文章摘自《C#高级编程(第 版)》定价 元 特价 元 购买

    XmlDocument及其派生类XmlDataDocument(详见本章后面的内容)是用于在 NET中表示DOM的类 与XmlReader 和 XmlWriter不同 XmlDocument具有读写功能 并可以随机访问DOM树 XmlDocument类似于MSXML中的DOM执行方式 如果您用MSXML编过程序 就会觉得使用XmlDocument很合适

    下面介绍的示例创建一个XmlDocument对象 加载磁盘上的一个文档 再从标题元素中加载带有数据的列表框 这类似于XmlReader一节的示例 区别是本例选择要使用的节点 而不是像XmlReader示例那样浏览整个文档

    下面是该示例的代码 与XmlReader示例相比 这个示例是比较简单的(该文件在下载的DOMSample 文件夹中)     private void button _Click(object sender System EventArgs e)     {        // doc is declared at the module level        // change path to match your path structure        doc Load( \\ \\ \\books xml );        // get only the nodes that we want        XmlNodeList nodeLst=doc GetElementsByTagName( title );        // iterate through the XmlNodeList        foreach(XmlNode node in nodeLst) listBox Items Add(node InnerText);     }

    注意 我们在本节的示例中添加了模块级的声明     private XmlDocument doc=new XmlDocument();

    如果这就是我们需要完成的工作 使用XmlReader加载列表框就是一种非常高效的方式 原因是我们只浏览一次文档 就完成了处理 这就是XmlReader的工作方式 但如果要重新查看某个节点 最好使用XmlDocument 扩展该示例 添加另一个事件处理程序(即DOMSample )     private void listBox _SelectedIndexChanged(object sender System EventArgs e)     {        //create XPath search string        string srch= bookstore/book[title= + listBox SelectedItem ToString()                                             + ] ;        //look for the extra data        XmlNode foundNode = doc SelectSingleNode(srch);        if(foundNode != null)           MessageBox Show(foundNode InnerText);        else           MessageBox Show( Not found );     }

    在这个示例中 与上一个示例一样 从books xml 文档中加载了带有标题的列表框 单击列表框 会引发SelectedIndexChanged()事件 获取列表框中所选项的文本(书名) 创建一个XPath 语句 把它传送给doc对象的SelectSingleNode() 方法 该方法返回title是书名的一部分的book元素(foundNode) 在消息框中显示节点的InnerText 继续单击列表框中的项目 此时文档已经加载 且一直到释放它之前 它都处于已加载状态

    下面简要介绍一下SelectSingleNode()方法 它是XmlDocument类的Xpath实现 SelectSingleNode ()和 SelectNodes()都是在XmlNode中定义的 而XmlDocument是基于XmlNode的 SelectSingleNode()返回一个XmlNode SelectNodes()返回一个XmlNodeList System Xml XPath命名空间包含许多Xpath实现 后面的一节会介绍它们     插入节点

    前面的示例使用XmlTextWriter创建一个新文档 其局限性是不能把节点插入到当前文档中 而使用XmlDocument类可以做到这一点 把上一个示例中的button _Click()事件处理程序作如下改动(在下载代码的DOMSample 中)

lishixinzhi/Article/program/net/201311/14751


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13369638.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-23
下一篇 2023-07-23

发表评论

登录后才能评论

评论列表(0条)

保存