2010-02-13 56 views
1

元素我想查詢使用的XDocument和LINQ to XML這個非常複雜的XML文檔。我想要執行以下操作:C#擴展在其中方法 - 辦案時未找到

獲取回答某個條件的所有元素,如果不符合,則返回xDocument中的另一個屬性。

例子:

<cars> 
    <car> 
     <patrol type="oil"> 
      <url> http://Toyotaoil.com </url> 
     </patrol> 
    </car> 
    <car> 
     <patrol type="oil"> 
      <url> http://BMWoil.com </url> 
     </patrol> 
     <patrol type="gas"> 
      <url> http://BMWgas.com </url> 
     </patrol> 
    </car> 
    <car> 
     <patrol type="gas"> 
      <url> http://Hondagas.com </url> 
     </patrol> 
    </car> 

現在我想從這個查詢得到的是油型巡邏的名單,除非汽車不使用汽油,然後我會很滿意加油站。

如果我使用where條款我只是想念那裏的車用氣體的情況下。有沒有像where條款,在那裏我可以指定,如果他們的條件沒有滿足於做這種事?

+0

頁面上的預覽部分出於某種原因,您應該確保在發佈之前正確格式化內容。 – 2010-02-13 12:27:44

回答

2

下面的解決方案應讓您靈活查詢不管你喜歡:

var result = from car in xdoc.Element("cars").Elements("car") 
      let patrols = car.Elements("patrol") 
      let oils = patrols.Where(patrol => patrol.Attribute("type") == "oil") 
      select new { 
        Car = car, 
        Patrols = (oils.Any() ? oils : patrols) 
      } 

我沒有的Visual Studio在這裏,所以我希望它編譯:)
提供更多關於你喜歡選擇什麼的信息,我會給你一個更具體的LINQ語句。

+0

這並沒有完全奏效,但我學到了一種全新的方法(使用let關鍵字),它指出我正確的方向......所以,謝謝! – vondip 2010-02-13 20:45:03

-1

根據您的規格Order按類型,採取FirstOrDefault()


編輯:我的意思是這樣的:

var patrols = from car in doc.Root.Elements() 
       let p = car.Elements().OrderBy(patrol=>patrol.Attribute("type").Value).First() 
       select p; 

這將返回每車一個結果。檢查OrderBy條款並相應地調整它。這將導致:

<patrol type="oil"> 
    <url> http://Toyotaoil.com </url> 
</patrol> 

<patrol type="gas"> 
    <url> http://BMWgas.com </url> 
</patrol> 

<patrol type="gas"> 
    <url> http://Hondagas.com </url> 
</patrol> 

再次編輯:啊,現在點擊它。是的,這只是返回每輛車一個單一的項目 - Zyphrax給了一個很好的解決方案。

+0

他試圖選擇多個項目,而不是一個。 – 2010-02-13 12:52:23

+0

@Jon:我沒有得到你的答案,也沒有得到你的答覆。請再次查看帖子。 – 2010-02-13 13:10:58

0

這聽起來像你實際上並不想要一個where子句 - 你只是想要一個select子句或者選擇一個值。

但是,您的示例並未真正描述如何根據值選擇不同的項目 - 您將選擇哪個「其他屬性」?你的意思是「汽車在哪裏使用汽油」?如果你可以給出更多的例子細節,那麼給你匹配的代碼不應該太難。

2
xdoc.Element("cars") 
    .Elements("car") 
    .Select(car => car.Elements("patrol") 
         .SingleOrDefault(p => (string)p.Attribute("type") == "oil") 
        ?? 
        car.Elements("patrol") 
         .Single(p => (string)p.Attribute("type") == "gas")); 
+0

這將導致只有一個油元素。如果我理解正確,應該返回所有石油巡邏要素(如果有的話),否則返回任何巡邏要素。 – Zyphrax 2010-02-13 13:23:40

1

你可以只讓這樣的事情:

var query = from element in someElements 
      select element.Attribute("type").Value == "oil" 
       ? returnSomethingWhenItIsOil 
       : returnSomethingWhenItIsSomethingElse; 

var query = from element in someElements 
      where element.Attribute("type") == "oil" 
       || element.Attribute("type") == "gas" 
      select element; 

但更好的說明問題,謝謝:)

+0

不完全正確,這將返回石油或天然氣。不只是石油或如果沒有石油,然後天然氣。 – Zyphrax 2010-02-13 13:19:10

+0

啊,現在我明白了;)感謝清理。然後,我想dtb的解決方案將做到這一點。 – 2010-02-13 13:21:52

0
     var cars = from c in xdoc.Descendants("car") 
         where 
         (c.Element("patrol").Attribute("type").Value == "oil" || 
         c.Element("patrol").Attribute("type").Value == "gas") 
         select new Car 
         { 
          FuelType = c.Element("patrol").Attribute("type").Value.ToString() 
         }; 

    foreach (Car c in cars) 
     { 
      Console.WriteLine(c.ToString()); 
     } 

    class Car 
    { 
     public string FuelType { get; set; } 
     public override string ToString() 
     { 
      return "Car FeulType = " + this.FuelType.ToString(); 
     } 
    } 

這些結果,我得到

alt text http://img694.imageshack.us/img694/5016/carse.jpg