2016-02-08 35 views
1

我有使用Linq的構建對象保存XML數據的問題。例如,我在url http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142中有XML數據。在MarketStat類我想抱着type id價值和MarketValue類陣列我想擁有的buysellall節點volumeavgmaxminstddevmedianpercentile值。我從來沒有使用LINQ到目前爲止所以請幫我解決在下面的代碼我的問題:C#使用Linq從XML中提取數據

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    internal class MarketValue 
    { 
     public int Volume { get; set; } 
     public double Avg { get; set; } 
     public double Max { get; set; } 
     public double Min { get; set; } 
     public double Stddev { get; set; } 
     public double Median { get; set; } 
     public double Percentile { get; set; } 
    } 
    internal class MarketStat 
    { 
     public string Name { get; set; } 
     public MarketValue[] MarketValueses { get; set; } 
    } 
    internal class Program 
    { 
     private static List<MarketStat> list; 
     internal static void Main(string[] args) 
     { 
      list = (
       from e in XDocument.Load("http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142"). 
        Root.Elements("marketstat") 
       select new MarketStat 
       { 
        Name = (string) e.Element("type id"), 
        MarketValueses = (
         from mv in e.Elements("buy") 
         select new MarketValue 
         { 
          Volume = (int) mv.Element("volume"), 
          Avg = (double) mv.Element("avg"), 
          Max = (double)mv.Element("max"), 
          Min = (double)mv.Element("min"), 
          Stddev = (double)mv.Element("stddev"), 
          Median = (double)mv.Element("median"), 
          Percentile = (double)mv.Element("percentile") 
         }).ToArray() 
       }).ToList(); 
     } 
    } 
} 
+0

您的鏈接僅返回一組數字,而不是任何XML。也許這個QA可以幫助你:http://stackoverflow.com/questions/10518372/how-to-deserialize-xml-to-object – John

+1

@John,它返回XML;可能你的瀏覽器只是把它當作HTML來處理,而不是原始的顯示。 – adv12

+0

好的注意。我認爲提到的質量保證將有助於序列化對象。 – John

回答

3

與您當前密碼的問題是,你想獲取type元素的id屬性,但是您要取它與type id這是錯誤的。你也有價值MarketValue在三個節點,即購買,出售&所有,但目前你只提取細節購買節點。

這應該給你所期望的輸出: -

XDocument xdoc = XDocument.Load("http://api.eve-central.c... 
var result = xdoc.Root.Elements("type") 
       .Select(ms => new MarketStat 
        { 
         Name = (string)ms.Attribute("id"), 
         MarketValueses = ms.Elements() 
             .Select(mv => new MarketValue 
             { 
              Volume = (long)mv.Element("volume"), 
              Avg = (double)mv.Element("avg"), 
              Max = (double)mv.Element("max"), 
              Min = (double)mv.Element("min"), 
              Stddev = (double)mv.Element("stddev"), 
              Median = (double)mv.Element("median"), 
              Percentile = (double)mv.Element("percentile") 
             }).ToArray() 
          }).ToList(); 
+0

代碼給了我一個空'結果'列表的錯誤。當我使用'Root.Elements(「marketstat」)。選擇(ms => new MarketStat''Name =(string)ms.Element(「type」)。Attribute(「id」)'輸入id'節點,但應該持有'buy'''''''all'的數組給我一個錯誤,請檢查我的代碼 – user5671675

+0

@ user5671675 - 是啊,因爲現在你有'evec_api'作爲根節點,所以這爲了遍歷XML,你需要告訴'type'節點存在於'marketstat'節點中,所以你的代碼應該是:'''''xdoc.Root('type')''xdoc.Root.Elements .Element(「marketstat」)。元素(「type」)'_Or否則,您可以直接獲取所有_type_節點,如下所示: - 'xdoc.Descendants(「type」)。Select ...' –

+1

謝謝。看看我的問題在哪裏,通過工作代碼,我將繼續使用XML文檔進行練習和技巧練習。 – user5671675

1

您正在尋找所謂的「類別ID」的元素。這不是XML中元素的有效名稱。你應該只查找名爲type元素...這是該元素的名稱:

<type id="34"> 

如果你想通過編號進行篩選,然後你可以獲取屬性id

您還試圖直接從marketstat元素獲取buy元素 - 它不在那裏;它在type元素內。基本上,您需要更多地關注XML的結構。

我的猜測是,你應該只能期待一個單一的buy元素 - 這使事情變得更簡單。我懷疑你不需要在結果的每個元素中都有一個數組...

0

你的xml解析有一些問題。

首先你不能調用類型ID,你在這裏做

Name = (string) e.Element("type id") 

id是類型元素的屬性,所以你會做這樣的事情

Name = e.Element("type").Attributes("id").Value 

另一個問題在你試圖迭代購買價值的部分。 您有以下行

from mv in e.Elements("buy") 

這不會起作用,因爲e是文檔的根元素。團購是類型元素的子元素,所以你會希望這樣的事情

from mv in e.Elements("type").Descendants("buy") 

希望這有助於並指出你在正確的方向

下面是一個工作示例

list = (
    from e in XDocument.Load("http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142"). 
     Root.Elements("marketstat") 
     let type = e.Element("type") 
    select new MarketStat 
    { 
     Name = type.Attribute("id").Value, 
     MarketValueses = (
      from mv in type.Descendants("buy") 
      select new MarketValue 
      { 
       Volume = long.Parse(mv.Element("volume").Value), 
       Avg = double.Parse(mv.Element("avg").Value), 
       Max = double.Parse(mv.Element("max").Value), 
       Min = double.Parse(mv.Element("min").Value), 
       Stddev = double.Parse(mv.Element("stddev").Value), 
       Median = double.Parse(mv.Element("median").Value), 
       Percentile = double.Parse(mv.Element("percentile").Value) 
      }).ToArray() 
    }).ToList(); 

**請注意,解析該XML時,音量值太大而無法放入int32值,因此我將其更改爲很長。