我正在尝试将XML字符串解析为列表,结果计数始终为零。
string result = "";
string address = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Read the whole contents and return as a string
result = reader.ReadToEnd();
}
XDocument doc = XDocument.Parse(result);
var ListCurr = doc.Descendants("Cube").Select(curr => new CurrencyType()
{ Name = curr.Element("currency").Value, Value = float.Parse(curr.Element("rate").Value) }).ToList();
我出错了。
答案 0 :(得分:5)
问题是你正在寻找没有命名空间的元素,而XML在根元素中包含它:
xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
指定任何元素的默认命名空间。此外,currency
和rate
是Cube
元素中的属性 - 它们不是子元素。
所以你想要这样的东西:
XNamespace ns = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref";
var currencies = doc.Descendants(ns + "Cube")
.Select(c => new CurrencyType {
Name = (string) c.Attribute("currency"),
Value = (decimal) c.Attribute("rate")
})
.ToList();
请注意,因为我将currency
属性转换为string
,所以对于未指定该属性的任何货币,您最终会得到一个空Name
属性。如果您想跳过这些元素,可以在Where
之前或之后使用Select
子句执行此操作。
另请注意,我已将Value
的类型更改为decimal
而不是float
- 您不应将float
用于与货币相关的值。 (有关详细信息,请参阅this question。)
此外,您应该考虑使用XDocument.Load
加载XML:
XDocument doc = XDocument.Load(address);
然后没有必要自己创建WebRequest
等。
答案 1 :(得分:2)
XDocument doc = XDocument.Parse(result);
XNamespace ns = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref";
var ListCurr = doc.Descendants(ns + "Cube")
.Where(c=>c.Attribute("currency")!=null) //<-- Some "Cube"s do not have currency attr.
.Select(curr => new CurrencyType
{
Name = curr.Attribute("currency").Value,
Value = float.Parse(curr.Attribute("rate").Value)
})
.ToList();