[Orcas] 19. LINQ to XML - Querying XML

[ 2007-09-22 18:05:16 | 作者: yuhen ]
字号: | |
为了让 XML 和 LINQ 相结合,微软是花了大力气的,System.Xml.Linq 几乎是对 System.Xml 的全部重写。

通过下面的例子,我们看看 LINQ to XML 的使用方法,并分析一下执行流程。

test.xml
<?xml version="1.0" encoding="utf-8"?>
<people>
    <person>
        <id>1</id>
        <name>user1</name>
        <age>1</age>
    </person>
    <person>
        <id>2</id>
        <name>user2</name>
        <age>2</age>
    </person>
    <person>
        <id>3</id>
        <name>user3</name>
        <age>2</age>
    </person>
</people>

使用 LINQ to XML 返回所有 person.name。
var doc = XDocument.Load("test.xml");

var q = from p in doc.Elements("people").Elements("person") select p;
foreach (var e in q)
{
    Console.WriteLine(e.Element("name").Value);
}

输出结果正确。接下来的过程分析比较有趣,注意看反编译代码。
[CompilerGenerated]
private static Func<XElement,XElement> Delegate1;

[CompilerGenerated]
private static XElement <Test>b__0(XElement p)
{
    return p;
}
        
private static void Test()
{   
    XDocument doc = XDocument.Load("test.xml");

    if (Program.Delegate1== null)
        Program.Delegate1= new Func<XElement,XElement>(null, Program.<Test>b__0);
    
    IEnumerable<XElement> q = Enumerable.Select<XElement,XElement>(
        Extensions.Elements<XElement>(
            doc.Elements("people"), "person"
        ), 
        Program.Delegate1
    );
}

整个过程包括:

(1) 调用 XDocument.Elements("people") 返回 IEnumerable<XElement>。
(2) 调用扩展方法 Extensions.Elements() 返回包含所有 "person" 的 IEnumerable<XElement> 集合对象。
(3) 而这时候调用的 Enumerable.Select<XElement,XElement> 就已经是我们所熟悉的 LINQ to Object 了。

uploads/200709/22_180941_1.gif


明白其执行流程,理解 LINQ to XML 就比较容易了。

XElement 类型提供了很多方法供我们进行操作。其中 Element() 用于获取第一个 Child Element 对象,Element 还重载了大量的显示转换操作符,我们可以直接用下面的方式来代替 Element.Value。
var doc = XDocument.Load("test.xml");

var q = from p in doc.Elements("people").Elements("person") select p;
foreach (var e in q)
{
    Console.WriteLine("Id={0}; Name={1}; Age={2}", 
        (int)e.Element("id"),
        (string)e.Element("name"),
        (int)e.Element("age"));
}

-------------------------

我们看看对 Attribute 的操作方法。

test.xml
<?xml version="1.0" encoding="utf-8"?>
<people>
    <person tag="a">
        <id>1</id>
        <name>user1</name>
        <age>1</age>
    </person>
    <person tag="a">
        <id>2</id>
        <name>user2</name>
        <age>2</age>
    </person>
    <person tag="b">
        <id>3</id>
        <name>user3</name>
        <age>2</age>
    </person>
</people>

找出所有 tag = a 的 person。
var doc = XDocument.Load("test.xml");

var q = from p in doc.Elements("people").Elements("person") 
        where p.Attribute("tag").Value == "a"
        select p;

foreach (var e in q)
{
    Console.WriteLine("Id={0}; Tag={1}",
        (int)e.Element("id"),
        (string)e.Attribute("tag"));
}

----------------

LINQ to XML 类型继承关系

uploads/200709/22_180945_2.gif
[最后修改由 yuhen, 于 2007-09-22 20:31:57]
评论Feed 评论Feed: http://www.rainsts.net/feed.asp?q=comment&id=567

浏览模式: 显示全部 | 评论: 2 | 引用: 0 | 排序 | 浏览: 5935
引用 sean*
[ 2007-09-22 19:06:26 ]
Elements("people").Elements("person")

笔误吧?

应该只有一次。
引用 yuhen
[ 2007-09-22 20:30:37 ]
你是说只有一个 Elements()? [rolleyes] 没错啊。
引用至 sean
Elements("people").Elements("person")
笔误吧?
应该只有一次。

发表评论
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
用户名:   密码:  
验证码 * 请输入验证码