2013-09-28 118 views
2

我想解析C#中的以下XML結構。我想用貨幣創建一個List>。在C#中使用重複的元素名稱解析XML?

<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"> 
<gesmes:subject>Reference rates</gesmes:subject> 
<gesmes:Sender> 
<gesmes:name>European Central Bank</gesmes:name> 
</gesmes:Sender> 
<Cube> 
    <Cube time="2013-09-27"> 
    <Cube currency="USD" rate="1.3537"/> 
    <Cube currency="JPY" rate="133.28"/> 
    <Cube currency="BGN" rate="1.9558"/> 
    <Cube currency="CZK" rate="25.690"/> 
    <Cube currency="DKK" rate="7.4573"/> 
    (....) 

我試過使用XDocument.Descendants,但它沒有返回任何東西。我猜這與Cube元素在幾個層面上使用的事實有關。

XDocument xdoc = XDocument.Parse(xml); 
var currencies = from cube in xdoc.Descendants("Cube") 
        select new 
         { 
          Currency = cube.Attribute("currency").Value, 
          Rate = cube.Attribute("rate").Value 
         }; 

foreach (var currency in currencies) 
    this.Add(new KeyValuePair<string, double>(currency.Currency, Convert.ToDouble(currency.Rate))); 

如何解析XML結構以獲取貨幣?

+0

與ECB完全相同的文件具有相同的問題時可以完成:)非常感謝@ L.B - 工作正常 – CeOnSql

回答

1

嘗試xdoc.XPathSelectElements(「//立方/立方/立方[@名稱=‘貨幣’]」)

1

您必須添加一個命名空間(立方體元素不是在默認空命名空間)和您必須檢查Cube元素是否確實具有貨幣屬性。

這是最接近解決您CURENT代碼,將工作:

XDocument xdoc = XDocument.Parse(xml); 
XNamespace nsSys = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"; 

var currencies = from cube in xdoc.Descendants(nsSys+ "Cube") 
       where cube.Attribute("currency") !=null 
       select new 
       { 
         Currency = cube.Attribute("currency").Value, 
         Rate = cube.Attribute("rate").Value 
       }; 

Used this Answer as reference

3

你有兩個問題與您的代碼

  • Cube沒有currencyrate屬性
  • 您忽略Xml命名空間

因爲它似乎要打造根據您的代碼字典

XNamespace ns = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"; 
var xDoc = XDocument.Load(fname); 

var dict = xDoc.Descendants(ns + "Cube") 
       .Where(cube => cube.Attributes().Any(a => a.Name == "currency")) 
       .ToDictionary(cube => cube.Attribute("currency").Value, 
          cube => (decimal)cube.Attribute("rate")); 

PS:你不必解析rate明確。它可以通過鑄造