Reputation: 7394
I'm trying to parse the following XML structure in C#. I want to create an List> with the currencies.
<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"/>
(....)
I've tried using XDocument.Descendants, but it's not returning anything. I'm guessing it has to do with the fact that the Cube-element is used in several levels.
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)));
How can I parse the XML structure to get the currencies?
Upvotes: 2
Views: 303
Reputation: 116188
You have two problems with your code
Cube
doesn't have currency
and rate
attributeSince it seems you want to create a dictionary according to your code:
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: You don't have to parse the rate
explicitly. It can be done while reading the xml by casting
Upvotes: 3
Reputation: 42494
You have to add a namespace (the Cube elements are not in the default empty namespace) and you have to check if the Cube element has indeed the currency attribute.
This is the closest solution to your curent code that will work:
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
};
Upvotes: 1