close

小小抱怨一下..

Linq 在.Net下的查詢,可以說是省去過去許多麻煩的事情

XML 是一種可以跨平台傳遞資料,很方便的一種文字檔

Linq  +   XML    =                   .............................................................................................................. 惡夢   >_<

XML 是一種有結構描述的文字檔,但在網路上對於 XML 與 Linq 的結合

問題不是找不到資料   問題在 網路 有太多太多的文章

.Net 的作法又包山包海   把過去 2002 在用的技術  到  2008 的東西 還是包在一起  (2010目前感覺在這段變化不大)

手邊沒有一本合適的工具書,也沒找到詳細的說明,坦白說  做了很多白工....

再這邊 做了些簡單的整理,希望可以減少大家對XML檔第一次接觸處理的速度


這邊有篇 對 XML 在.NET 環境下有詳細的介紹 ,對於VB.Net 下 XML的基本架構這篇是很不錯的說明,不過是XMLDocumenr,一樣可以在XDocument下使用
http://www.dotblogs.com.tw/yc421206/archive/2010/08/10/17108.aspx


XDocument 與   XMLDocument 的比較

目前最常可以找到處理.Net   處理  XML 主要有兩種格式

XDocument    與 XmlDocument  兩種Class   其中  XmlDocument  屬於 .Net 2.0 就推出的 Class    XDocument 是 .Net 3.5 推出的

簡單來說......就是  舊的可以不用了   ...........

不是說舊的不好,只是真的不好用........(對於Linq的處理 與  速度   與 XDocument 比起來真的比較弱)



XDocument 更進一步支援了 DataSet 與 Datatable
XDocument 更可以拆解成
    XMLSchema(資料結構描述) 與 
    XElement(資料主體)

或許是因為這樣   在做Linq 處理的速度比  XmlDocument 處理上快了許多,所以XMLDocument 就被我拋在一旁了 



XDocument 的運用

XML Schema 在大部分的時候是可以忽略的,除非想要直接與 DataSet 或 DataTable 做直接的連接

在大多數的情況下  直接用Xelement  與  Linq 來處理  XML 文件就綽綽有餘了



首先來個 簡單的運用  這邊有三筆資料存在檔案  123.xml


<root>
    <GlassList>
        <GlassID>123</GlassID>
        <ChipNo>1</ChipNo>
        <DateTime>2011/03/19 20:40:45</DateTime>
    </GlassList>
    <GlassList>
        <GlassID>456</GlassID>
         <ChipNo>1</ChipNo>
        <DateTime>2011/03/19 20:41:40</DateTime>
   </GlassList>
   <GlassList>
        <GlassID>789</GlassID>
         <ChipNo>2</ChipNo>
        <DateTime>2011/03/19 20:41:40</DateTime>
   </GlassList>
</root>




'將 XML 讀入 Xelement 很簡單     使用Load 這函數就可以了

Dim  XDoc as Xelement = Xelement.Load(123.xml)


重點來了  與  Linq 的結合

1. 宣告與法的差異
Dim Xquary1 as Xelement = From chip in XDoc.Descendants _
                                           Where Chip.Element("ChipNo").Value = 1 _
                                           Select chip


Dim Xquary2 = From chip in XDoc.Descendants _
                        Where Chip.Element("ChipNo").Value = 1 _
                        Select chip




這兩種查詢出來,結構都一樣,都是 XLinq 的集合
但使用上有點差別

如果要把 Xquary1 加入 XDoc  需用 AppendChild()

而如要把 Xquary2 加入 XDoc  需用 Add()

這是查詢出來的結果
   <GlassList>
        <GlassID>123</GlassID>
        <ChipNo>1</ChipNo>
        <DateTime>2011/03/19 20:40:45</DateTime>
    </GlassList>
    <GlassList>
        <GlassID>456</GlassID>
         <ChipNo>1</ChipNo>
        <DateTime>2011/03/19 20:41:40</DateTime>
   </GlassList>





2. Linq 時使用查詢方式的差異

大家可以發現,上面的範例 如果轉換DataTable 是符合第一正規化的,這也是為何可以把XML檔配合Schema後可以直接轉為DataTable
但如果查詢的資料不符合第一正規化,而且所需要抽出的資料不需要完整的整個Node,那就需要換另一個Function

下面兩片Glass範例

 Dim Xe As XElement = New XElement( _
  <root>
            <GlassAllList>
                <GlassList>
                    <GlassID>123</GlassID>
                    <Chip>
                        <ChipID>555</ChipID>
                        <ChipNum>1</ChipNum>
                        <ChipX>10</ChipX>
                        <ChipY>10</ChipY>
                        <ChipW>50</ChipW>
                        <ChipH>100</ChipH>
                    </Chip>
                    <Chip>
                        <ChipID>666</ChipID>
                        <ChipNum>2</ChipNum>
                        <ChipX>70</ChipX>
                        <ChipY>10</ChipY>
                        <ChipW>50</ChipW>
                        <ChipH>100</ChipH>
                    </Chip>
                    <DateTime>2011/03/19 20:40:45</DateTime>
                </GlassList>
                <GlassList>
                    <GlassID>456</GlassID>
                    <Chip>
                        <ChipID>234</ChipID>
                        <ChipNum>1</ChipNum>
                        <ChipX>10</ChipX>
                        <ChipY>10</ChipY>
                        <ChipW>50</ChipW>
                        <ChipH>100</ChipH>
                    </Chip>
                    <Chip>
                        <ChipID>444</ChipID>
                        <ChipNum>2</ChipNum>
                        <ChipX>70</ChipX>
                        <ChipY>10</ChipY>
                        <ChipW>50</ChipW>
                        <ChipH>100</ChipH>
                    </Chip>
                    <DateTime>2011/03/19 20:41:40</DateTime>
                </GlassList>
        </root>)

Dim aaa = From rr in Xe.Descendants.elements("Chip") _
                 where rr.elements("ChipID").value = 444 _
                 select rr

這樣就可以只取出Chip的資料

但這樣規劃有個問題,目前測不出如過要知道哪個Glass的Chip的ID 是444
要一次就把整個Glass的資料取出來,目前是辦不到的...或許有人可以幫忙測一下......

目前用到現在,資料最好還是符合第一正規化,在查詢資料時會比較順利

(這篇打了好久.....四天有了吧  -___________- )

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Rh 的頭像
    Rh

    程式狂想曲

    Rh 發表在 痞客邦 留言(0) 人氣()