根据列表

时间:2016-09-06 20:23:17

标签: c# linq linq-to-xml

我有一个存储在类中的xml元素列表:

public class clsField
{
    public string fieldName { get; set; }
}

然后我正在加载一个xml文件:

XDocument doc = XDocument.Load(fileName);

最后,我想只检索上面类中定义的字段到IEnumerable对象中。这就是我到目前为止所做的:

List<clsField> lstFieldsToProcess;          
IEnumerable<XElement> allthedocs = from thedoc
                 in doc.Descendants("thedocs")
                 select
                 (
                  from fields
                  in lstFieldsToProcess
                  select XElement.Parse(fields.fieldName)
                 );

但是上面的代码出错了。任何帮助,将不胜感激。先谢谢。

更新#1

伪代码:

var fieldNames = new HashSet<string>(lstFieldsToProcess.Select(c => c.fieldName));
IEnumerable<XElement> elems = from level1 in doc.Elements("thedocs")
                              let level2 = level1.Descendants()
                              where fieldNames.Contains(level2.Name.LocalName)
                              select level1;

1 个答案:

答案 0 :(得分:1)

我不太确定你要做什么。是否要过滤掉具有特定名称的所有元素,并且这些元素是名为&#34; thedocs&#34;?

的元素的后代

假设这是您想要做的,那么您可以执行以下操作:

IEnumerable<XElement> elems = from field in lstFieldsToProcess
                              from de in doc.Elements("thedocs").Descendants(field.fieldName)
                              select de;

// Of course this is the same:
IEnumerable<XElement> elems = lstFieldsToProcess
    .SelectMany(f => doc.Elements("thedocs").Descendants(f.fieldName));

我不确定XDocument的效率如何,所以也许最好先取出你想要匹配的字段名(如果性能对你很重要,请测试两者中哪一个更好):

var fieldNames = new HashSet<string>(lstFieldsToProcess.Select(c => c.fieldName));
IEnumerable<XElement> elems = from d in doc.Elements("thedocs").Descendants()
                              where fieldNames.Contains(d.Name.LocalName)
                              select d;

更新#1 我认为你的伪代码几乎可以自己使用。

var fieldNames = new HashSet<string>(lstFieldsToProcess.Select(c => c.fieldName));
IEnumerable<XElement> elems = from level1 in doc.Elements("thedocs")
                              from level2 in level1.Descendants()
                              where fieldNames.Contains(level2.Name.LocalName)
                              select level1;

虽然,这可以包含相同的&#34; thedocs&#34;元素多次(如果它有几个具有有效字段名的后代)。为避免这种情况,只需在结果上调用Distint()即可。