VS2008裡最革命性的改變應該就是Linq,雖然已改用VS2008好幾個月,但都是在趕些急如星火的ASP.NET 2.0專案,因此到目前為止只享受到Javascript Intellisense等周邊的IDE改良。

今天喘口氣,切換去處理另一個任務,裡面剛好有個需求,要寫個小工具做批次資料轉換。由於是一次性作業,平台語言可完全自訂,加上程式邏輯簡單,這種機會不拿來練功,下次不知要等到民國幾年。設好停損點(註: 如果多久沒搞定就放棄,改回用.NET 2.0寫),捲起袖子寫了我第一支應用Linq的小品程式。

情境如下: 資料來源為一隻getdata.asp,傳入不同的QueryString(?id=nnnn)可以逐筆取回資料,資料為XML格式,共有多個Group,每個Group有筆數不一的Row,Row的ItemID為為識別值。

<?xml version="1.0" encoding="utf-8"?>
<Result>
  <Group GroupID="群組1">
    <Row ItemID="02330BP" />
    <Row ItemID="52821BP" />
    <Row ItemID="10941BP" />
  </Group>
  <Group GroupID="群組2">
    <Row ItemID="03001BP" />
    <Row ItemID="60041BP" />
    <Row ItemID="20131BP" />
  </Group>
  <Group GroupID="群組3">
    <Row ItemID="90231BP" />
    <Row ItemID="10011BP" />
  </Group>
</Result>

由XML中取出Group跟Row的過程,用XmlDocument就可以輕鬆搞定,但這回我打算用Linq to XML來處理,算是練功。

Linq的寫法頗特殊,要花點時間熟悉,ScottGu寫了一篇很棒的Ling to XML tutorial,光靠著這篇Tutorial,居然就把程式寫完了。Check it out!

//宣告群組資料結構,用一個List<string>來存群組成員ItemID
public class ItemGroup
{
    public string Name;
    public List<string> Items;
}
 
static void Main(string[] args)
{
    string id = "1234";
    string getUrl = "http://remote_server/getdata.asp?id=" + id;
    
    //由ASP取回XML,做為XDocument的來源
    XDocument xd = XDocument.Load(getUrl);
    
    //由於要列出Group由Row,第一次就得用上SubQuery的技巧,真"硬斗"... orz 
    var groups = from groupNode in xd.Descendants("Group")
                 select new ItemGroup
                 {
                     Name = groupNode.Attribute("GroupID").Value,
                     Items = 
                            (
              from record in groupNode.Elements("Row")
                             select record.Attribute("ItemID").Value
                             ).ToList<string>()
                 };
    
    //用兩層foreach列出所有群組及成員
    foreach (ItemGroup grp in groups) 
    {
        Console.WriteLine("Name=" + grp.Name);
        foreach (string item in grp.Items) 
            Console.WriteLine(item);
    }
}

Comments

Be the first to post a comment

Post a comment