C# 用Linq的方式实现对Xml文件的基本操作(创建xml文件、增删改查xml文件节点信息)

  LINQ to XML 为创建 XML 元素提供了一种称为“函数构造”的有效方式。函数构造是指在单个语句中创建 XML 树的能力。  

启用函数构造的 LINQ to XML 编程接口有几个重要功能:

  XElement 构造函数可以对内容采用多种类型的参数。例如,可以传递另一个 XElement 对象,该对象将成为一个子元素。可以传递一个 XAttribute 对象,该对象将成为该元素的一个属性。也可以传递任何其他类型的对象,该对象将转换为字符串并成为该元素的文本内容。

  XElement函数采用类型为 Objectparams 数组,因此可以向该构造函数传递任意数目的对象。 这使您可以创建具有复杂内容的元素。如果对象实

IEnumerable<T>,则枚举对象中的集合,并添加集合中的所有项。

  如果集合包含 XElementXAttribute 对象,则单独添加集合中的每一项。这一功能很重要,因为它允许您将 LINQ 查询的结果传递给构造函数。

 

  本文的主要模块为:

    ① :生成xml文件

    ② :遍历xml文件的节点信息

    ③ :修改xml文件的节点信息

    ④ :向xml文件添加节点信息

    ⑤ :删除指定xml文件的节点信息


  ①:生成xml文件假设我们想生成这样的一个xml文件结构,如下所示:

    <? xml version="1.0" encoding="utf-8" ?>
-    < Users >
-     < User ID =" 111111 " >
        < name > EricSun </ name >
         < password > 123456 </ password >
        < description > Hello I'm from Dalian </ description >
       </ User >
-     < User ID =" 222222 " >
        < name > Ray </ name >
        < password > 654321 </ password >
         < description > Hello I'm from Jilin </ description >
      </ User >
    </ Users >
   用我的上篇文章也能够很容的实现,不过下面我要用Linq to xml的方式实现生成这个xml文件,请看下面代码:
复制代码
     
     
1 using System; 2   using System.Collections.Generic; 3   using System.Linq; 4   using System.Text; 5   using System.Xml.Linq; 6 7   namespace OperateXmlLinq 8 { 9 class Program 10 { 11 static void Main( string [] args) 12 { 13 // xml文件存储路径 14   string myXmlPath = " E:\\MyUsers.xml " ; 15 // 创建xml文件 16   GenerateXmlFile(myXmlPath); 17 } 18 19 private static void GenerateXmlFile( string xmlPath) 20 { 21 try 22 { 23 // 定义一个XDocument结构 24   XDocument myXDoc = new XDocument( 25 new XElement( " Users " , 26 new XElement( " User " , new XAttribute( " ID " , " 111111 " ), 27 new XElement( " name " , " EricSun " ), 28 new XElement( " password " , " 123456 " ), 29 new XElement( " description " , " Hello I'm from Dalian " ) 30 ), 31 new XElement( " User " , new XAttribute( " ID " , " 222222 " ), 32 new XElement( " name " , " Ray " ), 33 new XElement( " password " , " 654321 " ), 34 new XElement( " description " , " Hello I'm from Jilin " ) 35 ) 36 ) 37 ); 38 // 保存此结构(即:我们预期的xml文件) 39   myXDoc.Save(xmlPath); 40 } 41 catch (Exception ex) 42 { 43 Console.WriteLine(ex.ToString()); 44 } 45 } 46 }
复制代码
【注:由于使用了Linq to xml的方式,所以要引入命名空间System.Xml.Linq】,通过运行上面这段代码,就可以创建我们预想的xml文件结构,并且可以看出用Linq这种方式,在代码中就可以很清楚明了知道我们创建xml文件的结构(如:构造函数的参数所示)

  ②:【遍历xml文件的节点信息】创造出了xml文件之后,我们就要知道如何获得xml文件的各个节点的信息,请看如下代码:

复制代码
  
  
1 private static void GetXmlNodeInforOld( string xmlPath) 2 { 3 try 4 { 5 XDocument myXDoc = XDocument.Load(xmlPath); 6 XElement rootNode = myXDoc.Element( " Users " ); 7 foreach (XElement node in rootNode.Elements( " User " )) 8 { 9 Console.WriteLine( " User ID = {0} " , node.Attribute( " ID " ).Value); 10 11 string name = node.Element( " name " ).Value; 12 string password = node.Element( " password " ).Value; 13 string description = node.Element( " description " ).Value; 14 Console.WriteLine( " name = {0} \npassword = {1} \ndescription = {2} " , name, password, description); 15 } 16 } 17 catch (Exception ex) 18 { 19 Console.WriteLine(ex.ToString()); 20 } 21 } 22 23 private static void GetXmlNodeInformation( string xmlPath) 24 { 25 try 26 { 27 // 定义并从xml文件中加载节点(根节点) 28   XElement rootNode = XElement.Load(xmlPath); 29 // 查询语句: 获得根节点下name子节点(此时的子节点可以跨层次:孙节点、重孙节点......) 30 IEnumerable < XElement > targetNodes = from target in rootNode.Descendants( " name " ) 31 select target; 32 foreach (XElement node in targetNodes) 33 { 34 Console.WriteLine( " name = {0} " , node.Value); 35 } 36 37 // 查询语句: 获取ID属性值等于"111111"并且函数子节点的所有User节点(并列条件用"&&"符号连接) 38 IEnumerable < XElement > myTargetNodes = from myTarget in rootNode.Descendants( " User " ) 39 where myTarget.Attribute( " ID " ).Value.Equals( " 111111 " ) && myTarget.HasElements 40 select myTarget; 41 foreach (XElement node in myTargetNodes) 42 { 43 Console.WriteLine( " name = {0} " , node.Element( " name " ).Value); 44 Console.WriteLine( " password = {0} " , node.Element( " password " ).Value); 45 Console.WriteLine( " description = {0} " , node.Element( " description " ).Value); 46 } 47 } 48 catch (Exception ex) 49 { 50 Console.WriteLine(ex.ToString()); 51 } 52 }
复制代码

  上面用了两种方法去实现对xml文件节点信息的读取,第一种方法是那种比较老的模式:通过父节点获得它的子节点(一层一层的获得),然后获取目标节点的信息;第二中方法用到的是Linq to xml的查询模式,根据我们的需求获得符合条件的所有节点,然后对这些节点的信息进行读取。

  接下来我们要简单的讲述一下Linq to xml的查询模式(语法一看便懂,这里就不过多阐述了),LINQ to XML 的一个最重要的性能优势(与XmlDocument 相比)为:LINQ to XML 中的查询是静态编译的,而 XPath 查询则必须在运行时进行解释,此功能是 LINQ to XML 的内置功能。

  在调试程序的时候我们发现,第二种方法的IEnumerable<XElement> targetNodes = from target in rootNode.Descendants("name") select target;的这句话执行完毕后,得到的targetNodes依然是null,直到遍历的时候才获得相应的对象信息,这种方式就做延迟执行,【延迟执行】:意味着表达式的计算延迟,直到真正需要它的实现值为止。当必须操作大型数据集合,特别是在包含一系列链接的查询或操作的程序中操作时,延迟执行可以大大改善性能。在最佳情况下,延迟执行只允许对源集合的单个循环访问。

  【注:查询条件写在where语句中,并列条件用"&&"符号连接,或条件用"||"符号连接】

  ③:【修改xml文件的节点信息】知道了如何查询xml文件的节点信息之后,对相应节点信息做相应的修改,就显得很容易了。请看如下代码:

复制代码
  
  
1 private static void ModifyXmlNodeInforOld( string xmlPath) 2 { 3 try 4 { 5 XDocument myXDoc = XDocument.Load(xmlPath); 6 myXDoc.Element( " Users " ).Element( " User " ).Attribute( " ID " ).Value = " 777777 " ; 7 foreach (XElement node in myXDoc.Element( " Users " ).Elements( " User " ).Elements( " description " )) 8 { 9 node.SetValue( " Hello, I'm from China. " ); 10 } 11 myXDoc.Save(xmlPath); 12 } 13 catch (Exception ex) 14 { 15 Console.WriteLine(ex.ToString()); 16 } 17 } 18 19 private static void ModifyXmlNodeInformation( string xmlPath) 20 { 21 try 22 { 23 // 定义并从xml文件中加载节点(根节点) 24 XElement rootNode = XElement.Load(xmlPath); 25 // 查询语句: 获取ID属性值等于"222222"或者等于"777777"的所有User节点(或条件用"||"符号连接) 26 IEnumerable < XElement > targetNodes = from target in rootNode.Descendants( " User " ) 27 where target.Attribute( " ID " ).Value == " 222222 " || target.Attribute( " ID " ).Value.Equals( " 777777 " ) 28 select target; 29 // 遍历所获得的目标节点(集合) 30 foreach (XElement node in targetNodes) 31 { 32 // 将description节点的InnerText设置为"Hello, I'm from USA." 33 node.Element( " description " ).SetValue( " Hello, I'm from USA. " ); 34 } 35 // 保存对xml的更改操作 36 rootNode.Save(xmlPath); 37 } 38 catch (Exception ex) 39 { 40 Console.WriteLine(ex.ToString()); 41 } 42 }
复制代码

  这里也用了两种方法去获取相应节点信息的,具体过程请看代码就可以啦。

  ④:【向xml文件添加节点信息】下面的代码是向原有xml文件中添加一个节点

复制代码
  
  
1 private static void AddXmlNodeInformation( string xmlPath) 2 { 3 try 4 { 5 // 定义并从xml文件中加载节点(根节点) 6 XElement rootNode = XElement.Load(xmlPath); 7 // 定义一个新节点 8 XElement newNode = new XElement( " User " , new XAttribute( " ID " , " 999999 " ), 9 new XElement( " name " , " Rose " ), 10 new XElement( " password " , " 456123 " ), 11 new XElement( " description " , " Hello, I'm from UK. " )); 12 // 将此新节点添加到根节点下 13 rootNode.Add(newNode); 14 // 保存对xml的更改操作 15 rootNode.Save(xmlPath); 16 } 17 catch (Exception ex) 18 { 19 Console.WriteLine(ex.ToString()); 20 } 21 }
复制代码

  简单做一个总结:下面的方法将子内容添加到 XElement 或 XDocument 中:

  方法                 说明

  Add                  在 XContainer 的子内容的末尾添加内容。

  AddFirst           在 XContainer 的子内容的开头添加内容。

  下面的方法将内容添加为 XNode 的同级节点。 向其中添加同级内容的最常见的节点是 XElement,不过你也可以将有效的同级内容添加到其他类型的节点,

  例如 XText 或 XComment。

  方法                         说明

  AddAfterSelf            在 XNode 后面添加内容。

  AddBeforeSelf          在 XNode 前面添加内容。

  ⑤:【删除指定xml文件的节点信息】如何将刚刚加入的那个节点删除掉呢?请看如下代码:

复制代码
  
  
1 private static void DeleteXmlNodeInformation( string xmlPath) 2 { 3 try 4 { 5 // 定义并从xml文件中加载节点(根节点) 6 XElement rootNode = XElement.Load(xmlPath); 7 // 查询语句: 获取ID属性值等于"999999"的所有User节点 8 IEnumerable < XElement > targetNodes = from target in rootNode.Descendants( " User " ) 9 where target.Attribute( " ID " ).Value.Equals( " 999999 " ) 10 select target; 11 12 // 将获得的节点集合中的每一个节点依次从它相应的父节点中删除 13 targetNodes.Remove(); 14 // 保存对xml的更改操作 15 rootNode.Save(xmlPath); 16 } 17 catch (Exception ex) 18 { 19 Console.WriteLine(ex.ToString()); 20 } 21 }
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值