2013-09-28 92 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明确。它可以通过铸造