如何根据子属性过滤 XDocument 并保持父结构?
How to filter XDocument based on children attributes and keeping parent structure?
一棵xml树需要根据属性进行过滤。子元素与父元素同名。如果满足显示元素的条件,则需要显示该元素和所有父结构。
例如 xml 看起来像(深度是随机的):
<Root>
<Foo attr="xyz 123"></Foo>
<Foo attr="abc 111"></Foo>
<Foo attr="abc 222">
<Foo attr="abc 111"></Foo>
<Foo attr="abc 222">
<Foo attr="xyz 123"></Foo>
</Foo>
</Foo>
</Root>
过滤条件是,属性 "attr" 包含文本 "xyz"。过滤后 xml 应如下所示:
<Root>
<Foo attr="xyz 123"></Foo>
<Foo attr="abc 222">
<Foo attr="abc 222">
<Foo attr="xyz 123"></Foo>
</Foo>
</Foo>
</Root>
XDocument
用于保存树结构(后来XDocument_instance.Elements()
连接到WPF treeview)。
以下 Linq 命令仅对第一个元素级别(在根之后)进行排序:
var Elements = from el in xdoc.Root.Elements()
where
el.Attribute("attr").Value.Contains("xyz")
select el
如何创建应用所述过滤的 Linq 命令(或 foreach 循环)?
编辑:
首选解决方案不修改原始数据,而是为视图创建另一个(即 Linq 查询)。
您需要 Descendants()
,它将获取文档的所有子元素:
var Elements = from el in xdoc.Root.Descendants()
where
el.Attribute("attr").Value.Contains("xyz")
select el
// first make a list of elements that are to be removed
var forRemoval = new List<XElement>();
foreach (var element in xmlDoc.Descendants())
{
if (!element.DescendantsAndSelf().Any(e => e.Attribute("attr") != null && e.Attribute("attr").Value.Contains("xyz")))
{
forRemoval.Add(element);
}
}
// then remove the elements
foreach (var xElement in forRemoval)
{
xElement.Remove();
}
您可以使用以下 LINQ:
var Elements = from el in xdoc.Root.Elements()
where (el.Attribute("attr") != null && el.Attribute("attr").Value.Contains("xyz")) ||
(el.Descendants().Any(x => x.Attribute("attr") != null && x.Attribute("attr").Value.Contains("xyz")))
select el;
一棵xml树需要根据属性进行过滤。子元素与父元素同名。如果满足显示元素的条件,则需要显示该元素和所有父结构。
例如 xml 看起来像(深度是随机的):
<Root>
<Foo attr="xyz 123"></Foo>
<Foo attr="abc 111"></Foo>
<Foo attr="abc 222">
<Foo attr="abc 111"></Foo>
<Foo attr="abc 222">
<Foo attr="xyz 123"></Foo>
</Foo>
</Foo>
</Root>
过滤条件是,属性 "attr" 包含文本 "xyz"。过滤后 xml 应如下所示:
<Root>
<Foo attr="xyz 123"></Foo>
<Foo attr="abc 222">
<Foo attr="abc 222">
<Foo attr="xyz 123"></Foo>
</Foo>
</Foo>
</Root>
XDocument
用于保存树结构(后来XDocument_instance.Elements()
连接到WPF treeview)。
以下 Linq 命令仅对第一个元素级别(在根之后)进行排序:
var Elements = from el in xdoc.Root.Elements()
where
el.Attribute("attr").Value.Contains("xyz")
select el
如何创建应用所述过滤的 Linq 命令(或 foreach 循环)?
编辑: 首选解决方案不修改原始数据,而是为视图创建另一个(即 Linq 查询)。
您需要 Descendants()
,它将获取文档的所有子元素:
var Elements = from el in xdoc.Root.Descendants()
where
el.Attribute("attr").Value.Contains("xyz")
select el
// first make a list of elements that are to be removed
var forRemoval = new List<XElement>();
foreach (var element in xmlDoc.Descendants())
{
if (!element.DescendantsAndSelf().Any(e => e.Attribute("attr") != null && e.Attribute("attr").Value.Contains("xyz")))
{
forRemoval.Add(element);
}
}
// then remove the elements
foreach (var xElement in forRemoval)
{
xElement.Remove();
}
您可以使用以下 LINQ:
var Elements = from el in xdoc.Root.Elements()
where (el.Attribute("attr") != null && el.Attribute("attr").Value.Contains("xyz")) ||
(el.Descendants().Any(x => x.Attribute("attr") != null && x.Attribute("attr").Value.Contains("xyz")))
select el;