Linq to xml,检索基于通用接口的列表

时间:2010-06-01 17:56:44

标签: c# xml linq

我有一个看起来像这样的XML文档

    <Elements>
     <Element>
      <DisplayName />
      <Type />
     </Element>
    </Elements>

我有一个界面,

interface IElement
{
    string DisplayName {get;}
}

和几个派生类:

public class AElement: IElement

public class BElement: IElement

我想要做的是编写最有效的查询来迭代XML并根据'Type'属性创建包含IElementAElement的{​​{1}}列表在XML中。

到目前为止,我有这个:

BElement

但这只适用于IEnumerable<AElement> elements = from xmlElement in XElement.Load(path).Elements("Element") where xmlElement.Element("type").Value == "AElement" select new AElement(xmlElement.Element("DisplayName").Value); return elements.Cast<IElement>().ToList(); 。有没有办法在同一个查询中添加AElement,并将其设为通用BElement?或者我是否必须为每个派生类型运行此查询一次?

2 个答案:

答案 0 :(得分:6)

您可以使用条件运算符:

IEnumerable<IElement> elements = 
    from xmlElement in XElement.Load(path).Elements("Element")
    let type = (string)xmlElement.Element("Type")
    let name = (string)xmlElement.Element("DisplayName")
    select type == "AElement"
         ? (IElement)new AElement(name)
         : (IElement)new BElement(name);

或者,使用常规语法:

IEnumerable<IElement> elements =
    XElement.Load(path)
            .Elements("Element")
            .Select(xmlElement =>
{
    var type = (string)xmlElement.Element("Type");
    var name = (string)xmlElement.Element("DisplayName");

    switch (type)
    {
        case "AElement": return (IElement)new AElement(name);
        case "BElement": return (IElement)new BElement(name);
    }

    throw new Exception();
});

答案 1 :(得分:0)

IEnumerable<IElement> elements = 
    from e in XElement.Load(path).Elements("Element")
    let elType = e.Element("Type").Value
    let elName = e.Element("Name").Value
    where elType == "AElement" || elType == "BElement" 
    select 
        elType == "AElement" 
            ? (IElement) new AElement( name )
            : (IElement) new BElement( name );