基于列表从 XDocument 中检索特定元素
Retrieving specific elements from an XDocument based on a list
我有一个 xml 元素的列表存储在 class:
public class clsField
{
public string fieldName { get; set; }
}
然后我正在加载一个 xml 文件:
XDocument doc = XDocument.Load(fileName);
最后,我只想将上面 class 中定义的字段检索到 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;
我不太确定你想做什么。您是否要过滤掉所有具有特定名称且是名为 "thedocs" 的元素的后代的元素?
假设这是您想要做的,那么您可以执行以下操作:
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;
不过,这可以多次包含相同的 "thedocs" 元素(如果它有多个具有有效字段名的后代)。为避免这种情况,只需对结果调用 Distint()。
我有一个 xml 元素的列表存储在 class:
public class clsField
{
public string fieldName { get; set; }
}
然后我正在加载一个 xml 文件:
XDocument doc = XDocument.Load(fileName);
最后,我只想将上面 class 中定义的字段检索到 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;
我不太确定你想做什么。您是否要过滤掉所有具有特定名称且是名为 "thedocs" 的元素的后代的元素?
假设这是您想要做的,那么您可以执行以下操作:
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;
不过,这可以多次包含相同的 "thedocs" 元素(如果它有多个具有有效字段名的后代)。为避免这种情况,只需对结果调用 Distint()。