如何使用linq为嵌套节点动态添加到列表?

时间:2010-11-02 05:54:14

标签: c# linq

假设我有一个名为Woah的结构。 Woah有一个字段用于存储下面SomeChild的值,但也包含List<Woah>以包含其他Woah结构。我正在阅读的XML具有以下结构:

<WoahWrapper>
  <Woahs>
    <WoahNode>
      <SomeChild />
      <SubWoahs>
         <WoahNode />
      </SubWoahs>
     </WoahNode>
   </Woahs>
</WoahWrapper>

所以在这里我可以将SomeChild分配给我在我的linq中的“select new”中创建的结构,但是有一种方法可以在我的结构中轻松初始化该列表并将其添加到所有{{}存在于WoahNode

中的1}}
SubWoahs

1 个答案:

答案 0 :(得分:1)

首先,DTO制造糟糕的结构;结构应该是值(不是实体),不可变的和小的。你的哇也不是这些。它应该是一个班级。

这里的一种方法可能是递归函数,对于位逻辑,你可以(如果你选择)重写为匿名方法:

var mapData = XDocument.Parse(xml);

Func<XElement, Woah> builder = null;
builder = c => {
    var woah = new Woah { SomeChild = (int)c.Element("SomeChild") };
    foreach(var sub in c.Elements("SubWoahs").Elements("WoahNode"))
        woah.Children.Add(builder(sub));
    return woah;
};
var list = (from c in mapData.Root.Element("Woahs").Elements("WoahNode")
            select builder(c)).ToList();

但是,个人我认为XmlSerializer在这里会更简单......

XmlSerializer ser = new XmlSerializer(typeof(WoahWrapper));
var list = ((WoahWrapper)ser.Deserialize(new StringReader(xml))).Woahs;

类型:

public class WoahWrapper
{
    private List<Woah> woahs = new List<Woah>();
    [XmlArray("Woahs"), XmlArrayItem("WoahNode")]
    public List<Woah> Woahs { get { return woahs; } }
}
public class Woah
{
    public int SomeChild { get; set; }
    private List<Woah> children;
    [XmlArray("SubWoahs"), XmlArrayItem("WoahNode")]
    public List<Woah> Children { get { return children ?? (
        children = new List<Woah>()); } }
}