c#进入了3.0时代,引入了强大的Linq,同时提供了Linq to Xml,这个全新的Xml Api。与Linq to Xml相比,传统的DOM Api就显得笨重而繁杂了。

Linq to Xml的本质

    首先,linq to xml是一种in-memory的技术(官方说法是:LINQ to XML provides an in-memory XML programming interface that leverages the .NET Language-Integrated Query (LINQ) Framework. LINQ to XML uses the latest .NET Framework language capabilities and is comparable to an updated, redesigned Document Object Model (DOM) XML programming interface.),也就是说,如果用Linq to Xml去打开一个Xml,也就会占用相应的内存。所以和DOM一样,在极端情况下,会出现内存不足。

    其次,linq to xml从本质上来说,就是linq to object+一套Xml Api,与linq to sql和linq to entity framework不同,后两者是使用特定的Linq Provider去翻译成对应系统的语言。

Linq to Xml的表现

    撇开理论的东西,还是来看看最简单的表现吧。如果要创建这样一个Xml:

<?xml version="1.0" encoding="utf-8" ?>
<persons>
  <person>
    <firstName>Zhenway</firstName>
    <lastName>Yan</lastName>
    <address>http://www.cnblogs.com/vwxyzh/</address>
  </person>
  <person>
    <firstName>Allen</firstName>
    <lastName>Lee</lastName>
    <address>http://www.cnblogs.com/allenlooplee/</address>
  </person>
</persons>

    我们只需要这样一句语句(vb.net可以更简单,当然这个超出了本文的范围):

XDocument doc = new XDocument(
    new XDeclaration("1.0", "utf-8", null),
    new XElement("persons",
        new XElement("person",
            new XElement("firstName", "Zhenway"),
            new XElement("lastName", "Yan"),
            new XElement("address", "http://www.cnblogs.com/vwxyzh/")
            ),
        new XElement("person",
            new XElement("firstName", "Allen"),
            new XElement("lastName", "Lee"),
            new XElement("address", "http://www.cnblogs.com/allenlooplee/")
            )
        )
    );

    看起来还行,构造一个Xml要比DOM方式简单的多,不过比起直接写Xml还是复杂了点,不过这个方式也可以这么用:

var persons = new[]
    {
        new
        {
            FirstName = "Zhenway",
            LastName = "Yan",
            Address = "http://www.cnblogs.com/vwxyzh/"
        },
        new
        {
            FirstName = "Allen",
            LastName = "Lee",
            Address = "http://www.cnblogs.com/allenlooplee/"
        }
    };
XDocument doc = new XDocument(
    new XDeclaration("1.0", "utf-8", null),
    new XElement("persons",
        from person in persons
        select new XElement("person",
            new XElement("firstName", person.FirstName),
            new XElement("lastName", person.LastName),
            new XElement("address", person.Address)
            )
        )
    );

    这样,就可以看出Linq to Xml在通过外部数据构造Xml的便捷性(vb.net的方式更加简洁)。

    在来看看Linq to Xml的查询:

            XDocument doc = XDocument.Parse(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<persons>
  <person>
    <firstName>Zhenway</firstName>
    <lastName>Yan</lastName>
    <address>http://www.cnblogs.com/vwxyzh/</address>
  </person>
  <person>
    <firstName>Allen</firstName>
    <lastName>Lee</lastName>
    <address>http://www.cnblogs.com/allenlooplee/</address>
  </person>
</persons>");
            foreach (var item in doc.Root.Descendants("address"))
            {
                Console.WriteLine((string)item);
            }

    这里,要注意Descendants方法的签名:

public IEnumerable<XElement> Descendants(XName name);

    参数类型是XName,而传的是一个string,这个为什么是合法的哪?来看看XName中的一个定义:

public static implicit operator XName(string expandedName);

    原来有个隐式转换,这样就好理解了,编译器自动调用了隐式转换。

    再来看一个更加复杂的查询:

            XDocument doc = XDocument.Parse(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<persons>
  <person>
    <firstName>Zhenway</firstName>
    <lastName>Yan</lastName>
    <address>http://www.cnblogs.com/vwxyzh/</address>
  </person>
  <person>
    <firstName>Allen</firstName>
    <lastName>Lee</lastName>
    <address>http://www.cnblogs.com/allenlooplee/</address>
  </person>
</persons>");
            foreach (var item in from person in doc.Root.Descendants("person")
                                 where (string)person.Element("firstName") == "Zhenway"
                                 select (string)person.Element("address"))
            {
                Console.WriteLine(item);
            }

    那么有namespace的Xml如何用Linq to Xml来处理哪?

    To be continued.

posted on 2009-11-14 15:02  Zhenway  阅读(935)  评论(0编辑  收藏  举报