• LINQ TO XML实用解析


    http://www.freecsstemplates.org/

    在开始将之前,先请大家看一下本节的标题,没错!是"LINQ TO XML实用解析",所以在这一节里我会以实用为主,向大家一步一步讲解LINQ TO XML的知识。

         首先解释一下什么是LINQ to XML?LINQ to XML 是一种启用了 LINQ 的内存 XML 编程接口,使用它,可以在 .NET Framework 编程语言中处理 XML。 LINQ to XML之前,我们主要通过XML DOM来创建XML文档对象。下面我给大家演示一下如何通过XML DOM创建文档对象。

    示例:

    private static void UserXMLDOMCreateXML()

            {

                XmlDocument xDocument = new XmlDocument();

                XmlElement xRoot = xDocument.CreateElement("Persons");

                XmlElement xPerson = xDocument.CreateElement("Person");

                XmlElement xPName = xDocument.CreateElement("Name");

                xPName.InnerText = "Olive"; 

                XmlElement xAge = xDocument.CreateElement("Age");

                xAge.InnerText = "22";

                XmlElement xPerson1 = xDocument.CreateElement("Person");

                XmlElement xPName1 = xDocument.CreateElement("Name");

                xPName1.InnerText = "Ares";

                XmlElement xAge1 = xDocument.CreateElement("Age");

                xAge1.InnerText = "23";

                XmlElement xPerson2 = xDocument.CreateElement("Person");

                XmlElement xPName2 = xDocument.CreateElement("Name");

                xPName2.InnerText = "Only";

                XmlElement xAge2 = xDocument.CreateElement("Age");

                xAge2.InnerText = "23";

                XmlElement xPerson3 = xDocument.CreateElement("Person");

                XmlElement xPName3 = xDocument.CreateElement("Name");

                xPName3.InnerText = "Love";

                XmlElement xAge3 = xDocument.CreateElement("Age");

                xAge3.InnerText = "23";

                xPerson.AppendChild(xPName);

                xPerson.AppendChild(xAge);

                xRoot.AppendChild(xPerson);

                xPerson1.AppendChild(xPName1);

                xPerson1.AppendChild(xAge1);

                xRoot.AppendChild(xPerson1);

                xPerson2.AppendChild(xPName2);

                xPerson2.AppendChild(xAge2);

                xRoot.AppendChild(xPerson2);

                xPerson3.AppendChild(xPName3);

                xPerson3.AppendChild(xAge3);

                xRoot.AppendChild(xPerson3);

                xDocument.AppendChild(xRoot);

                xDocument.Save(@"D:\LinqToXml.xml");

            }

    结果如下:

    下面再使用LINQ To XML的方式,创建一个XML文档对象。

    示例:

     private static void UseLINQXMLCreateXML()

            {

                XElement xElement = new XElement("Persons",

                    new XElement("Person",

                        new XElement("Name","Olive"),

                        new XElement("Age","22")),

                    new XElement("Person",

                        new XElement("Name","Ares"),

                        new XElement("Age","23")),

                    new XElement("Person",

                        new XElement("Name","Only"),

                        new XElement("Age","23")),

                    new XElement("Person",

                        new XElement("Name","Love"),

                        new XElement("Age","22"))

                );

                xElement.Save(@"D:\LINQ To XML.xml");

            }

    结果如下:

     

    通过以上结果可以发现,我们通过Linq To XML的方式创建XML文档对象,比XML DOM方式要剩下很多的代码,使用起来也更方便、高效。

    好了,通过这个例子我想你已经基本上学会了使用LINQ TO XML的方式创建XML文档,但是还有一些相关的东西,让我来为你细细道来。

    我们看一般的XML文件里边都有注释,如果我们想要为我们所创建的文档添加注释该怎么办呢?

    请看示例:

    刚刚我们已经创建了XML文档对象,可是如果需求有变化需要向该对象添加新的子项这时该怎么办呢?

    我们可以同过XElement.Add()的方法向XML文档对象添加新元素

    请看示例:

       private static void AddNewXMLItem()

            {

               

                XElement xe = new XElement("Pseron",new XElement("Name", "Remote"),new XElement("Age", "23"));

                xElement.Add(xe);

                xElement.Save(@"D:\LINQ To XML.xml");

                Console.WriteLine("元素添加成功!");

            }

    结果如下:

     

    由此可知通过XElement.Add()方法,可以像XML文档对象添加新的元素,但是添加的元素,默认都添加在文档对象的末尾,如果想要添加到文档开头怎么办呢?

    可以使用XElement.AddFirst()方法

    示例:

    XElement xe = new XElement("Pseron",new XElement("Name", "Snow"),new XElement("Age", "23"));

                xElement.AddFirst(xe);

                xElement.Save(@"D:\LINQ To XML.xml");

                Console.WriteLine("元素添加成功!");

    结果:

     

    除此之外还有AddAfterSelf()和AddBeforeSelf()方法,作用分别是:紧跟在此节点之后(之前)添加指定的内容。这里就不再做示例了。

    说完了添加,如果要删除元素该怎么办呢?

    通常我们会用XElement.Remove()方法或者XElement.RemoveAll()(为删除所有元素)

    请看下面的示例:

    //删除XML文档对象的第一元素

    xElement.Elements("Person").First().Remove();

    结果:

     

    //删除XML文档对象中Name元素值为Ares<Person>节点

      xElement.Elements("Person").Elements("Name").Where(p => p.Value == "Ares").Remove();

    结果:

     

    和上边的结果图对比可知Name"Ares"的节点已经被删除了。

    同样,如果我们想要查找某个节点也可这样做。请看上示例:

    //查询XML文档对象中Name元素的值为“Love”的<Person>节点,并将其内容输出

    示例: private static void SerachXMLItem()

            {

                Console.WriteLine("查询结果:");

                XElement x = xElement.Elements("Person").Where(p => p.Element("Name").Value == "Love").FirstOrDefault();

                Console.WriteLine(x.ToString());

            }

    结果:

     

    学会了查找,修改XML文档对象的指定内容就更加容易了。

    ////查询XML文档对象中Name元素的值为“Love”的<Person>节点,并将其内容做如下修改,<Name>Momo</Name>,<Age>22</Age>

    示例:

     private static void SerachXMLItem()

            {

                Console.WriteLine("查询结果:");

                XElement x = xElement.Elements("Person").Where(p => p.Element("Name").Value == "Love").FirstOrDefault();

                Console.WriteLine("修改前查询到的信息:");

                Console.WriteLine(x.Element("Name").ToString());

                Console.WriteLine(x.Element("Age").ToString());

                x.Element("Name").Value = "MoMo";

                x.Element("Age").Value = "22";

                Console.WriteLine("修改后的结果:");

                Console.WriteLine(x.ToString());

            }

    结果:

     

    原来Name值为LoveXML文档的最后,修改后Name值成为了"Momo"

    至此,我想大家已经学会了Linq To XML的基本的增删改查新建等一些的操作,你有没有发现这里边用到了很多我们在开始这个系列课程学习时,学习的一些C#3.0的新特性呢,Lamdba在这里用的比较多,还有一些Linq的查询函数用到的之前讲的扩展方法,但是这些还远远的不够,在下面,我会仔细的把一些相关Linq To XML的东西再深入的讲解一下。

    在实际的开发中可能需要为某些特定的元素添加一些额外的属性,通过下边的这个示例,我会向你展示,添加、修改、删除属性的方法。

    示例:

    //Name值为LovePerson添加地址属性,属性值为“北京”

        Console.WriteLine("为特定的元素添加地址属性:");

                XElement x = xElement.Elements("Person").Where(p => p.Element("Name").Value == "Love").FirstOrDefault();

                 x.SetAttributeValue("Address", "北京");

                 Console.WriteLine(x.ToString());

    结果:

     

    示例:

    //修改Name值为LovePerson的地址属性,修改属性值为“郑州”

    示例:

     private static void ChangeAttribute()

            {

                Console.WriteLine("修改特定元素的地址属性:");

                XElement x = xElement.Elements("Person").Where(p => p.Element("Name").Value == "Love").FirstOrDefault();

                x.SetAttributeValue("Address", "郑州");

                Console.WriteLine(x.ToString());

            }

    结果:

     

    如果想要删除属性的话,也很简单,只需要将要删除的属性值设为null就可以了

    示例:

     private static void DeleteAttribute()

            {

                Console.WriteLine("删除特定属性");

                XElement x = xElement.Elements("Person").Where(p => p.Element("Name").Value == "Love").FirstOrDefault();

                x.SetAttributeValue("Address", null);

            }

    结果:

     

    总而言之,与属性有关的操作都在XElement.SetAttributeValue()这个方法里。

    在有些时候我们想要替换文档对象中的某些元素,请注意是“替换”而不是修改,那么你可以这样做:

    示例: 使用ReplaceAll()替换元素

    private static void ReplaceXElement()

            {

                Console.WriteLine("ReplaceAll()替换特定元素");

                XElement x = xElement.Elements("Person").Where(p => p.Element("Name").Value == "Love").FirstOrDefault();

                Console.WriteLine("替换前");

                Console.WriteLine(x.ToString());

                x.ReplaceAll("O(_)O哈哈~");

                Console.WriteLine("替换后");

                Console.WriteLine(x.ToString());

            }

    结果:

     

    示例:将特定的元素替换为一个新的元素 

    private static void ReplaceXElement()

            {

                Console.WriteLine("ReplaceAll()替换特定元素");

                XElement x = xElement.Elements("Person").Where(p => p.Element("Name").Value == "Love").FirstOrDefault();

                Console.WriteLine("替换前");

                Console.WriteLine(x.ToString());

                x.ReplaceWith(new XElement("ZhiYe",

                                        new XElement("Name","Olive"),

                                        new XElement("Job","Sudent")));

            }

    结果:

     

    以上我们讲的这些都是在新建的文档对象里进行的操作,有时候我们可能会需要从已存在的文档中加载文档内容,一般可以通过XDocument类的静态的Load()方法,也可以通过使用XElement.Load()方法来完成这样的操作。XElementLoad方法是一种轻量级的方法,不需要新建文档对象,使用起来也比较方便,所以下面的示例就主要将一下使用XElement.Load()方法来加载已存在的文档。

    private static void XElementLoad()

            {

                XElement root= XElement.Load(@"D:\LINQ To XML.xml");

                XElement x=  root.Elements("Person").Where(p => p.Element("Name").Value == "Olive").FirstOrDefault();

                Console.WriteLine(x.ToString());

            }

    结果:

     

    在实际的开发中我们可能会需要从现有的XML文档中读取信息,然后和返回相应的信息集合,在WindowsPhone 7的开发中,有时候我们就需要加载本地的XML数据,然后返回数据集合与ListBox进行绑定。

    下边就做这样一个获取数据集合的小例子:

    首先根据XML的结构特点创建一个相应的Person类:

    public class Person

       {

           public string Name{get;set;}

           public string Age{get;set;}

       }

    示例:返回数据集合

    private static void JiHe()

            {

                 //xml文档读取信息,并转换为相应的Person类集合

                List<Person> psersonList = XElement.Load(@"D:\LINQ To XML.xml").Elements("Person").Select(p => new Person

                {

                    Name = p.Element("Name").Value,

                    Age = p.Element("Age").Value

                }).ToList();

                Console.WriteLine("输出从XML文档中读取的集合对象!");

                foreach (Person p in psersonList)

                {

                    Console.WriteLine("姓名:" + p.Name + "   年龄:" + p.Age);

                }

            }

    结果:

     

    好了,到这里已经把比较实用的Linq To Xml操作的所有方法都讲过了,希望可以对大家有所帮助,这里主要以实用为主,当然还有其他的一些方法和相关的操作类都没有讲到,如果有兴趣的朋友可以自己去关注一下。下一节,主要会将Linq To Sql的操作,这个也是比较常用和重要的。希望大家多多指导!

    这一几天一直在回顾事务相关的知识,也准备把以前了解皮毛的知识进行一些深入总结,虽然这一些知识并没有用到,但是了解其实现原理还是很有必要的,因为知道了原理,你也能把它实现出来。

    在上一节事务的编程模型里面,主要说明了三种编程模型,一般情况下,我们都接触的是单一资源的事务,也就是单独对一个数据库进行操作。如果需要跨多个资源保证事务一致性

    举个例子:在ATM机取钱的时候,需要对用户的账户进行扣款处理,然后发送一条消息给消息服务器(假设消息服务器是用JMS实现的),由消息服务器异步通过短信通知用户。如果用户取款失败,那么消息服务器不应该发送短信给用户。如何保证 用户帐务扣款 和 消息服务器的消息保持一致性,也就是说 取款成功,消息服务器就持久化消息,然后发送短信给用户,取款失败,消息服务器就回滚消息,啥都不做。

    在上面这种情况下,就需要使用分布式事务,也就是跨越多个资源的保证数据一致性。

    X/Open DTP(X/Open Distributed Transaction Processing Reference Model) 是X/Open 这个组织定义的一套分布式事务的标准,也就是了定义了规范和API接口,由这个厂商进行具体的实现。这个思想在java 平台里面到处都是。

    X/Open DTP 定义了三个组件: AP,TM,RM

    AP(Application Program):也就是应用程序,可以理解为使用DTP的程序

    RM(Resource Manager):资源管理器,这里可以理解为一个DBMS系统,或者消息服务器管理系统,应用程序通过资源管理器对资源进行控制。资源必须实现XA定义的接口

    TM(Transaction Manager):事务管理器,负责协调和管理事务,提供给AP应用程序编程接口以及管理资源管理器

    其中,AP 可以和TM 以及 RM 通信,TM 和 RM 互相之间可以通信,DTP模型里面定义了XA接口,TM 和 RM 通过XA接口进行双向通信,例如:TM通知RM提交事务或者回滚事务,RM把提交结果通知给TM。AP和RM之间则通过RM提供的Native API 进行资源控制,这个没有进行约API和规范,各个厂商自己实现自己的资源控制,比如Oracle自己的数据库驱动程序。

    下面一幅图说明了三者的关系:

    其中在DTP定了以下几个概念:

    事务:一个事务是一个完整的工作单元,由多个独立的计算任务组成,这多个任务在逻辑上是原子的。

    全局事务:对于一次性操作多个资源管理器的事务,就是全局事务

    分支事务:在全局事务中,某一个资源管理器有自己独立的任务,这些任务的集合作为这个资源管理器的分支任务

    控制线程:用来表示一个工作线程,主要是关联AP,TM,RM三者的一个线程,也就是事务上下文环境。简单的说,就是需要标识一个全局事务以及分支事务的关系。

    两阶段提交协议:如果一个事务管理器管理着多个资源管理器,如果控制全局事务和分支事务,在DTP里面说明两阶段提交的协议

    第一阶段:准备阶段

    事务管理器通知资源管理器准备分支事务,资源管理器告之事务管理器准备结果

    第二阶段:提交阶段

    事务管理器通知资源管理器提交分支事务,资源管理器告之事务管理器结果

    下面一幅图演示了正常情况下的两阶段提交,

    如果第一阶段某一个资源预提交失败,第二阶段就回滚第一阶段已经预提交成功的资源

     以上是比较正常的情况,但是由于RM有权利自己根据情况提交或者回滚自己的分支事务(官方说法是:Heuristic Decision)那三么就可能出现以下种情况:

    1 在TM通知RM提交事务之前,RM分支事务已经提交

    2 在TM通知RM提交事务之前,RM分支事务全部回滚

    3 在TM通知RM提交事务之前,RM分支事务部分回滚

    对于Heuristic Decision标记的分支事务,在没有TM通知RM forget 它之前,RM都必须保存分支事务的信息,等到TM从失败中恢复事务之后,通知RM forget 分支事务,这个时候RM才真正的完成事务。

    对于前面两种情况来说,TM会比较好处理,做事务恢复的时候,要么标记全局事务成功,要么标记全局事务回滚,通知RM可以完成分支事务了。对于第三种情况,可能就需要进行决策了,这个具体怎么处理,貌似DTP并没有说明细节,可以交给应用自己去判断。

    DTP编程模型

    虽然DTP内部的实现比较复杂,但是对于DTP编程模型就比较简单了

    1 AP通过TM获取事务

    2 AP申明需要哪些RM,TM注册RM

    3 AP使用RM完成分支事务

    4 AP通过TM提交事务

    5 TM通知RM提交事务

    而DTP的服务的实现就需要考虑以下几个问题:

    • 如何获取TM?
    • 如何启动和结束一个事务
    • 如何标识一个事务
    • 如何保存和传递事务上下文
    • 应用如何通过资源管理器操作共享资源
    • 资源管理器如何实现准备阶段以及与提交阶段的逻辑
    • 如何实现两阶段提交协议
    • 如何实现在异常情况下进行事务恢复

    其实如果把这几个问题了解清楚了,就可以自己实现一个两阶段提交的分布式事务模型了。

    爱公司的程序员 
    博客园blog地址:http://www.cnblogs.com/aigongsi/ 
    本人版权归作者和博客园所有,欢迎转载,转载请注明出处。

  • 相关阅读:
    Android系统API综述
    Android中的WeakReference 弱引用
    Android代码编译环境配置 “Gerrit和Git环境配置”
    Android源代码下载 “Gerrit下载源代码”
    Android源代码编译过程及指令
    Android的Launcher启动流程 “Launcher部分启动流程”
    Android Frameworks的base目录内容分析 “Android Frameworks base”
    Android系统源代码目录结构 “Android源代码”“目录结构”
    (Android UI)Android应用程序中资源:图片、字符串、颜色、布局等
    (Android UI)Action Bar
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2720282.html
Copyright © 2020-2023  润新知