处理XML的新方式——LINQ to XML

何谓LINQ?

LINQ即.NET 语言集成查询(.NET Language-Integrated Query (LINQ) Framework),为.NET架构中的重要组成部分。LINQ系列技术提供了针对对象(LINQ)、关系数据库(LINQ to SQL)和XML(LINQ to XML)的一致性查询体验。

什么是LINQ to XML?

LINQ to XML 使用最新的.NET Framework语言功能,相当于更新和重新设计的文档对象模型(DOM)XML编程接口。使用它,可以在.NET Framework编程语言中处理XML。

它将XML文档置于内存中,这一点很像文档对象模型(DOM)。你可以查询和修改XML文档,修改后,可以将其另存为文件,也可以将其序列化然后通过网络发送。但是,LINQ to XML与DOM不同:它提供一种新的对象模型,这好似一种更轻量的模型,使用也更方便,这种模型利用了Visual C# 2008在语言方面的改进。

LINQ to XML 最重要的优势是它与LINQ的集成。由于实现了这一集成,所以,可以对内存XML文档编写查询,以检索元素的属性和集合。LINQ to XML的查询功能与XPath和XQuery(两种老式的XML标准检索机制)具有可比性。Visual C# 2008集成LINQ后,可提供更强的类型化功能、编译时检查和改进的调试器支持。


如何使用LINQ查询?

所有的LINQ查询操作都可以由三个不同的操作组成:

1、获取数据源。

2、创建查询。

3、执行查询。

数据源可以为任意可查询类型,即支持IEnumerable或IEnumerable 接口及其派生接口的类型。

int[] numbers = new int[7]{0,1,2,3,4,5,6};

var numQuery =

        from num in numbers

        where (num % 2) == 0

        select num;

foreach(int num in numQuery)

{

    console.Write("{0,1} ",num);

}

上例实现从一个int数组中检索出所有偶数。其中数据源为numbers数组。

该查询表达式包含三个子句(如果对SQL熟悉,则不会陌生,但是语句顺序是不一样的):from、where和select。from 子句指定数据源,where 子句应用筛选器,select 子句指定返回的元素类型。

注意,var numQuery =...语句只是构建一个查询表达式,执行时并不会立即检索数据,当执行到下面的foreach语句时,才会检索数据。

当然,并不是必须使用foreach才能检索出结果,这个是可控的:

对于聚合函数如Count、Max、Average、First等,这些查询仅仅返回单个值而非集合,此时就不用使用foreach来检索结果了:

var numQuery =

        from num in numbers

        where (num % 2) == 0

        select num;

int numCount = numQuery.Count();

也可以强制立即执行查询结果并缓存,可调用ToList 或ToArray 方法:

List numQuery =

        (from num in numbers

        where (num % 2) == 0

        select num).ToList();

关于var

在C#中并没有"变体"变量的说法,即所有的变量都必须在申明时指定变量类型,var意义上并非JavaScript中的var,但也不代表一种确切的类型。在C#中var表示一种推断"类型",它指示编译器根据初始化语句右侧的表达式推断变量的类型。推断的类型可以是内置类型、匿名类型、用户定义类型、.NET Framework类库中定义的类型或任何表达式。即,var是一种简化写法,在程序编译时,编译器自动将var关键字替换成正确的类型:

var s = "Hello";  //var编译成string类型

var a = new[] {0,1,2}; //var编译成int[]

而上例中的var numQuery 将被编译成IEnumberable 。

以上仅对LINQ查询做简单介绍,实际上LINQ与SQL一样是复杂灵活的,同样可实现SQL的排序、分组等基本功能,读者如有兴趣深入了解,请参照MSDN。

如何创建XML树?

LINQ to XML 为创建XML元素提供了一种称为"函数构造"(即指在单个语句中创建XML树)的有效方式。

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

XElement类构造函数可采用Object的参数数组,由此可以一次性地传递任意数目的对象。这可以方便地构造出复杂内容的元素。如果参数中的对象实现了IEnumerable ,则枚举对象中的集合,并添加集合中的所有项。如果集合包含XElement或XAttribute对象,则单独添加集合中的每一项。这表示你可以直接使用LINQ查询的结果来构造新的XML树。

XElement contacts =

    new XElement("Contacts",

        new XElement("Contact",

            new XElement("Name", "Patrick Hines"),

            new XElement("Phone", "206-555-0144"),

            new XElement("Address",

                new XElement("Street1", "123 Main St"),

                new XElement("City", "Mercer Island"),

                new XElement("State", "WA"),

                new XElement("Postal", "68042")

            )

        )

    );

上例XML结果:

   

        Patrick Hines

        206-555-0144

       

            123 Main St

            Mercer Island

            WA

            68042

       

   

下例将使用LINQ的查询结果来构建XML树:

XElement srcTree =

    new XElement("Root",

        new XElement("Element", 1),

        new XElement("Element", 2),

        new XElement("Element", 3),

        new XElement("Element", 4),

        new XElement("Element", 5)

    );

XElement xmlTree =

    new XElement("Root",

    new XElement("Child", 1),

    new XElement("Child", 2),

    from el in srcTree.Elements()

    where (int)el > 2

    select el

);

Console.WriteLine(xmlTree);

结果:

    1

    2

    3

    4

    5

克隆还是附加?

在将XNode(包括XElement)或XAttribute对象添加到新树时,如果新内容没有父级,则直接将这些对象附加到XML树中。如果新内容已经有父级,并且是另一XML树的一部分,则克隆新内容,并将新克隆的内容附加到XML树。

XElement xmlTree1 = new XElement("Root",

    new XElement("Child1", 1)

);

XElement child2 = new XElement("Child2", 2);

XElement xmlTree2 = new XElement("Root",

    xmlTree1.Element("Child1"),

    child2

);

上例,xmlTree2树中,由于Child1属于xmlTree1树,固添加到xmlTree2时为克隆方式,即如果后续修改树1的此节点,树2中的节点不会变化。而child2添加到树2的时候采用的是附加方式,即后续程序修改了变量child2,那么对应的树2节点也会发生变化。

待续...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值