我有一个存储在类中的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;
答案 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()即可。