• 黄聪:Linq初级班 Linq To XML体验(高级编程篇)


    Linq初级班 Linq To XML体验(高级编程篇)

    首先,我们在Linq初级班 Linq To XML体验(基础)Linq初级班 Linq To XML体验(编程篇)了解了一些XML的基本知识以及如何用LINQ to XML对XML文档进行简单的操作,本文将继续深入LINQ to XML,做一些高级编程的演示.我也是LINQ的初学者,文章中不免会有一些不对的地方,希望高手们多多指点,为我们LINQ初学者们多提宝贵的意见,我也会继续努力的,本文章目录如下所示:

    目录

    1.Linq to XML函数构造

    2.Linq to XML批注

    3.Linq to XML轴

    4.Linq to XML事件

    1.Linq to XML函数构造

    函数构造是指通过单个语句构建XML树的能力.在Linq初级班 Linq To XML体验(编程篇)中我们已经体验了如何使用XElement和XAttribute类手工创建XML树,也可以通过其他XElement和XAttribute对象传递给XElement类的构造函数来创建子元素和属性,也就是说,LINQ查询的结果可以用来创建XML树,下面就来看看一个演示:

    代码
    //-----------------------------------------------------------
    // All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
    //-----------------------------------------------------------

    using System;
    using System.Xml.Linq;
    using System.Linq;

    namespace ConsoleApplication1
    {
    class Program
    {
    static void Main(string[] args)
    {
    XElement xel
    = new XElement(new XElement("Root",
    new XElement("Person",
    new XElement("Name", "Huang Cong"),
    new XElement("Sex", ""),
    new XElement("Age", 22)),
    new XElement("Person",
    new XElement("Name", "Li Si"),
    new XElement("Sex", ""),
    new XElement("Age", 12))
    ));

    //通过LINQ查询将xel的元素添加至新的XElement中
    XElement newXel = new XElement(new XElement("NewRoot",
    new XElement("Persons",
    xel.Elements().Where(u
    => u.Name == "Person").Select(u => u)
    )));

    Console.WriteLine(newXel);
    }
    }
    }

    运行结果:

    2.Linq to XML批注

    LINQ to XML批注是指将一个对象添加或关联到一个XML节点或者属性,批注可以是任何类型的任何对象,可以通过XElement或XAttribute类的AddAnnotation方法来添加批注,需要注意的是:当调用AddAnnotation方法时,是将一个新的对象添加至相应的元素或属性上,原先绑定的批注并不会被删除掉,如果想删除批注,可以调用RemoveAnnotations方法:

    代码
    //-----------------------------------------------------------
    // All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
    //-----------------------------------------------------------

    using System;
    using System.Xml.Linq;
    using System.Linq;

    namespace ConsoleApplication1
    {
    class Program
    {
    public class Test
    {
    public int Id { get; set; }
    public string Info { get; set; }
    }

    static void Main(string[] args)
    {
    XElement xel
    = new XElement(new XElement("Root",
    new XElement("Person", "Huang Cong")));

    //为元素添加2个批注
    xel.Element("Person").AddAnnotation(new Test() { Id = 1, Info = "测试1" });
    xel.Element(
    "Person").AddAnnotation(new Test() { Id = 2, Info = "测试2" });
    Console.WriteLine(
    "为元素添加2个批注:");
    var query
    = xel.Element("Person").Annotations<Test>().Select(u => u);
    foreach (var q in query)
    {
    Console.WriteLine(q.Info);
    }
    Console.WriteLine(
    "-------------------------------------");

    //删除所有批注
    xel.Element("Person").RemoveAnnotations<Test>();

    Console.WriteLine(
    "删除所有批注:");
    query
    = xel.Element("Person").Annotations<Test>().Select(u => u);
    foreach (var q in query)
    {
    Console.WriteLine(q.Info);
    }
    Console.WriteLine(
    "-------------------------------------");
    }
    }
    }

    运行结果:

    3.Linq to XML轴

    LINQ to XML提供了对XML的查询功能,以查找特定的元素或者属性并返回它们的值,LINQ to XML的轴方法让你可以轻松实现以上的功能,LINQ to XML还提供了返回个别节点的方法,这可以让开发人员处理更细粒度的细节.下面是几个主要的轴方法:
    1.  Descendants和DescendantsAndSelf
    2.  Ancestors和AncestorsAndSelf
    3.  ElementsAfterSelf和ElementBeforeSelf
    下面分别给各个方法做示例讲解:

    3.1   Descendants和DescendantsAndSelf

    Descendants方法返回指定元素的后继元素的集合,不包括元素本身,而DescendantsAndSelf则包括元素本身.

    代码
    //-----------------------------------------------------------
    // All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
    //-----------------------------------------------------------

    using System;
    using System.Xml.Linq;
    using System.Linq;

    namespace ConsoleApplication1
    {
    class Program
    {
    static void Main(string[] args)
    {
    XElement xel
    = new XElement(new XElement("Root",
    new XElement("Person",
    new XElement("Name", "Huang Cong"),
    new XElement("Age", 22)),
    new XElement("Person",
    new XElement("Name", "Li Si"),
    new XElement("Age", 12))
    ));

    Console.WriteLine(
    "遍历所有元素:");
    var des
    = xel.Descendants();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");

    Console.WriteLine(
    "遍历所有名称为Person的元素,不包括本身:");
    des
    = xel.Descendants("Person").Descendants();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");

    Console.WriteLine(
    "遍历所有名称为Person的元素,包括本身:");
    des
    = xel.Descendants("Person").DescendantsAndSelf();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");
    }
    }
    }

    运行结果:

    3.2   Ancestors和AncestorsAndSelf

    Ancestors方法返回指定节点的上级元素,不包括元素本身,而AncestorsAndSelf则包括元素本身.

    代码
    //-----------------------------------------------------------
    // All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
    //-----------------------------------------------------------

    using System;
    using System.Xml.Linq;
    using System.Linq;

    namespace ConsoleApplication1
    {
    class Program
    {
    static void Main(string[] args)
    {
    XElement xel
    = new XElement(new XElement("Root",
    new XElement("Person",
    new XElement("Name", "Huang Cong"))
    ));

    Console.WriteLine(
    "遍历所有元素:");
    var des
    = xel.Descendants();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");

    Console.WriteLine(
    "遍历所有名称为Name的元素的上级元素集合,不包括本身:");
    des
    = xel.Element("Person").Element("Name").Ancestors();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");

    Console.WriteLine(
    "遍历所有名称为Name的元素的上级元素集合,包括本身:");
    des
    = xel.Element("Person").Element("Name").AncestorsAndSelf();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");
    }
    }
    }

    运行结果:

    3.3   ElementsAfterSelf和ElementBeforeSelf

    ElementsAfterSelf方法和ElementBeforeSelf方法分别返回指定元素之后的元素和值指定元素之前的元素,也可以指定条件返回指定的元素集合.

    代码
    //-----------------------------------------------------------
    // All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
    //-----------------------------------------------------------

    using System;
    using System.Xml.Linq;
    using System.Linq;

    namespace ConsoleApplication1
    {
    class Program
    {
    static void Main(string[] args)
    {
    XElement xel
    = new XElement(new XElement("Root",
    new XElement("Person",
    new XElement("Name", "Huang Cong"),
    new XElement("Sex",""),
    new XElement("Age",12)))
    );

    Console.WriteLine(
    "获取Name元素之后的元素集合:");
    var des
    = xel.Element("Person").Element("Name").ElementsAfterSelf();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");

    Console.WriteLine(
    "获取Name元素之后的名为Sex的元素集合:");
    des
    = xel.Element("Person").Element("Name").ElementsAfterSelf("Sex");
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");

    Console.WriteLine(
    "获取Age元素之前的元素集合:");
    des
    = xel.Element("Person").Element("Age").ElementsBeforeSelf();
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");

    Console.WriteLine(
    "获取Age元素之前的名为Sex的元素集合:");
    des
    = xel.Element("Person").Element("Age").ElementsBeforeSelf("Sex");
    foreach (var d in des)
    {
    Console.WriteLine(d);
    }
    Console.WriteLine(
    "----------------------------------");
    }
    }
    }

    运行结果:

    4.Linq to XML事件

    在对XML树进行修改的时候,LINQ to XML事件会提供通知,LINQ to XML提供了2个事件来响应XML树的修改:Changing和Changed.当修改XML树时这2个时间会相继被触发.从运行结果我们可以看出,更新动作实际上是一个删除操作加上一个添加完成的:

    代码
    //-----------------------------------------------------------
    // All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
    //-----------------------------------------------------------

    using System;
    using System.Xml.Linq;
    using System.Linq;

    namespace ConsoleApplication1
    {
    class Program
    {
    static void Main(string[] args)
    {
    XElement xel
    = new XElement(new XElement("Root",
    new XElement("Person",
    new XElement("Name", "Huang Cong"),
    new XElement("Sex",""),
    new XElement("Age",12)))
    );

    xel.Changing
    += new EventHandler<XObjectChangeEventArgs>(xel_Changing);
    xel.Changed
    += new EventHandler<XObjectChangeEventArgs>(xel_Changed);

    //修改Person元素的Age元素值
    xel.Element("Person").SetElementValue("Age", 22);
    }

    static void xel_Changed(object sender, XObjectChangeEventArgs e)
    {
    Console.WriteLine(
    "触发Changed事件:");
    Console.WriteLine(
    "ChangedValue:{0} \tObjectChange:{1}", ((XNode)sender).ToString(), e.ObjectChange);
    Console.WriteLine(
    "------------------------------------");
    }

    static void xel_Changing(object sender, XObjectChangeEventArgs e)
    {
    Console.WriteLine(
    "触发Changing事件:");
    Console.WriteLine(
    "ChangingValue:{0} \tObjectChange:{1}", ((XNode)sender).ToString(), e.ObjectChange);
    Console.WriteLine(
    "------------------------------------");
    }
    }
    }

    运行结果:

    警告:不允许在被触发事件的执行过程中修改XML树,特别不要在事件中修改触发事件发生的节点,因为这会导致不可预测的结果.不过可以在事件中修改另外一个XML树.

    小结:

    LINQ to XML提供了大量方便的方法和接口给开发人员操作XML文档,这大大的提高了开发效率,希望本章的内容对你有所帮助哈,我也是LINQ的初学者,文章中不免会有一些不对的地方,希望高手们多多指点,为我们LINQ初学者们多提宝贵的意见,我也会继续努力的~~

    相关文章

    1.LinQ初体验 简单的示例(原创)

    2.Linq初体验 Linq2SQL示例(原创)

    3.Linq推迟查询的执行(原创)

    4.Ling初体验 匿名类型在查询表达式中的使用

    5.Linq初级班 标准查询操作符的使用和调用

    6.Linq初级班 Linq To XML体验(编程篇)

    7.Linq初级班 Linq To XML体验(基础篇)

    8.Linq初级班 Linq To XML体验(高级编程篇)

  • 相关阅读:
    C++之函数模板
    Boost库初见
    C++之异常处理
    C++之运行时类型识别RTTI
    Qt5.4静态编译方法
    Altium Designer极坐标布局方法
    PM2.5空气质量指数(AQI)是如何计算的
    emWin学习课堂
    uboot 下更改NAND的分区 fdisk
    gps 数据解析-NMEA 0183协议
  • 原文地址:https://www.cnblogs.com/huangcong/p/1922894.html
Copyright © 2020-2023  润新知