根据子元素值LINQ选择父XML(整个层次结构)元素
本文关键字:元素 XML 层次结构 选择 LINQ | 更新日期: 2023-09-27 18:14:29
我有以下XML和查询通过ID,如何获得父层次
<Child>
<Child1 Id="1">
<Child2 Id="2">
<Child3 Id="3">
<Child4 Id="4">
<Child5 Id="5"/>
<Child6 Id="6"/>
</Child4>
</Child3>
</Child2>
</Child1>
</Child>
在本例中,如果我查询(Id = 4)并在特定元素中使用Linq找出父元素,如何使用Hierarchy获得以下输出。
<Child>
<Child1 Id="1">
<Child2 Id="2">
<Child3 Id="3">
<Child4 Id="4"/>
</Child3>
</Child2>
</Child1>
</Child>
假设只需要一个节点父树:
string xml = @"<Child>
<Child1 Id="1">
<Child2 Id="2">
<Child3 Id="3">
<Child4 Id="4">
<Child5 Id="5"/>
<Child6 Id="6"/>
</Child4>
</Child3>
</Child2>
</Child1>
</Child>";
TextReader tr = new StringReader(xml);
XDocument doc = XDocument.Load(tr);
IEnumerable<XElement> myList =
from el in doc.Descendants()
where (string)el.Attribute("Id") == "4" // here whatever you want
select el;
// select your hero element in some way
XElement hero = myList.FirstOrDefault();
foreach (XElement ancestor in hero.Ancestors())
{
Console.WriteLine(ancestor.Name); // rebuild your tree in a separate document, I print ;)
}
要搜索树的每个元素,使用select查询迭代检索节点,不使用where子句,并为每个元素调用foreach。
根据所提供的示例XML,一旦找到了需要查找的节点,就可以沿着树向上查找父节点:
string xml =
@"<Child>
<Child1 Id='1'>
<Child2 Id='2'>
<Child3 Id='3'>
<Child4 Id='4'>
<Child5 Id='5'/>
<Child6 Id='6'/>
</Child4>
</Child3>
</Child2>
</Child1>
</Child>";
var doc = XDocument.Parse( xml );
// assumes there will always be an Id attribute for each node
// and there will be an Id with a value of 4
// otherwise an exception will be thrown.
XElement el = doc.Root.Descendants().First( x => x.Attribute( "Id" ).Value == "4" );
// discared all child nodes
el.RemoveNodes();
// walk up the tree to find the parent; when the
// parent is null, then the current node is the
// top most parent.
while( true )
{
if( el.Parent == null )
{
break;
}
el = el.Parent;
}
在Linq to XML中有一个方法叫做AncestorsAndSelf
on XElement
返回包含此元素的元素集合,以及
但是它不会按照你想要的方式转换你的XML树。
你想要的是:
- 对于给定的元素,查找父元素
- 删除父元素中除指定元素外的所有元素
- 从给定元素中删除所有元素
Linq中类似这样的内容(无错误处理):
XDocument doc = XDocument.Parse("<xml content>");
//finding element having 4 as ID for example
XElement el = doc.Descendants().First(el => el.Attribute("Id").Value == "4");
el.RemoveNodes();
XElement parent = el.Parent;
parent.RemoveNodes();
parent.Add(el);
[编辑]doc.ToString()
必须给你你想要的字符串。
[编辑]
- 使用
RemoveNodes
代替RemoveAll
,最后一个也删除属性。 - 也从所选元素中移除节点。
我找到了以下方法
XElement elementNode = element.Descendants()
.FirstOrDefault(id => id.Attribute("id").Value == "4");
elementNode.RemoveNodes();
while (elementNode.Parent != null)
{
XElement lastNode = new XElement(elementNode);
elementNode = elementNode.Parent;
elementNode.RemoveNodes();
elementNode.DescendantsAndSelf().Last().AddFirst(lastNode);
}
返回或打印elementNode