[英]How can I read a complete XML element here?
我有一个XML文件,其中包含一些Unit
:
<Unit Name="Length">
<Prefix Char="c"
IsSelected="false"
Factor="1"/>
<Prefix Char="d"
IsSelected="true"
Factor="104"/>
</Unit>
我想阅读整个对象:
public static Dictionary<string, Unit> Units { get; set; }
public class Prefix
{
public Func<double, double> fnc = null;
public Prefix(string c, double f, bool i, bool ifix = false,string fn = null)
{
Char = c;
Factor = f;
IsFixed = ifix;
Unit.funcs.TryGetValue(fn, out fnc);
}
public bool IsSelected { get; set; }
public bool IsFixed { get; set; }
public double Factor { get; set; }
public string Char { get; set; }
}
public Unit() { }
public Unit(string n, List<Prefix> p)
{
_name = n;
Prefixes = p;
}
private List<Prefix> _prefixes;
public List<Prefix> Prefixes
{
get { return _prefixes; }
set { _prefixes = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
....
}
我现在有这个:
Form.Units = (data.Descendants("Unit").Select(x => new Unit
(
x.Attribute("Name").Value,
(List<Prefix>) x.Descendants("Prefix").Select(p => new Prefix(
p.Attribute("Char").Value,
Convert.ToDouble(p.Attribute("Factor").Value),
p.Attribute("IsSelected").Value == "true",
p.Attribute("IsFixed").Value == "true",
p.Attribute("Func").Value)
)
)
)
).ToDictionary(x => x.Name, x => x);
并得到以下错误:
“无法将类型为'WhereSelectEnumerableIterator
2[System.Xml.Linq.XElement,DD.Prefix]' to type 'System.Collections.Generic.List
1 [DD.Prefix]'”。
显然(List<Prefix>)
那么查询将是什么? 如何获取列表<>中的内容?
。
它不是一个列表,而是一个查询,因此您不仅可以将其转换为列表,还可以调用ToList对其进行枚举并返回一个列表:
Form.Units = (data.Descendants("Unit").Select(x => new Unit
(
x.Attribute("Name").Value,
//(List<Prefix>) no casting needed
x.Descendants("Prefix").Select(p => new Prefix(
p.Attribute("Char").Value,
Convert.ToDouble(p.Attribute("Factor").Value),
p.Attribute("IsSelected").Value == "true",
p.Attribute("IsFixed").Value == "true",
p.Attribute("Func").Value)
).ToList() // you had an IEnumerable<Prefix> now this is a List<Prefix>
)
)
).ToDictionary(x => x.Name, x => x);
为了扩展我的评论,这里有几件事。 首先,可以在.Select
上使用.ToList()
扩展方法,将IEnumerable<T>
集合转换为List<T>
。
其次,如果查询中缺少任何属性或元素,您将获得空引用异常。 您可以通过显式转换为string
(然后根据需要转换结果)来安全地处理此问题。
更新后的查询如下所示:
Form.Units = (data.Descendants("Unit").Select(x => new Unit
((string)x.Attribute("Name"),
x.Descendants("Prefix").Select(p => new Prefix(
(string)p.Attribute("Char"),
Convert.ToDouble((string)p.Attribute("Factor")),
(string)p.Attribute("IsSelected") == "true",
(string)p.Attribute("IsFixed") == "true",
(string)p.Attribute("Func")).ToList()
)
)
)
).ToDictionary(x => x.Name, x => x);
请注意,使用(string)
时不需要.Value
(因为.Value
已经是string
)。
我将以以下方式表示此代码:。因为它避免执行将这些类型限制为IEnuermable表达式的参数构造函数。 即避免对要用于查询的类型进行参数构造。
我要Decendents
在XmlElement
/ x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / x / Decendents
中使用的类型中的类型。
此外,此代码段不包含Unit.funcs.TryGetValue(fn, out fnc);
..并且假定Prefix
类型上有属性名称Func
。 您可以在分配/设置过程中执行空检查。
data.Descendants("Unit")
.Select<XmlElement, Unit>(x => new Unit()
{
Name = x.Attribute("Name").Value,
Prefixes = x.Descendants("Prefix").Select<XmlElement, Prefix>(p => new Prefix()
{
Char = p.Attribute("Char").Value,
Factor = Convert.ToDouble(p.Attribute("Factor").Value),
IsSelectd = p.Attribute("IsSelected").Value == "true",
IsFixed = p.Attribute("IsFixed").Value == "true",
Func = p.Attribute("Func").Value
}).ToList()
})
.Select<Unit, KeyValuePair<string, Unit>>(unit => new KeyValuePair<string, Unit>()
{
Key = x.Name,
Value = x
})
.ToList()
.ForEach( kvp => {
Form.Units.Add(kvp.Key, kvp.Value);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.