C# 基于子元素值LINQ选择父XML(整个层次结构)元素
我有下面的XML和通过ID的查询,如何获得父层次结构C# 基于子元素值LINQ选择父XML(整个层次结构)元素,c#,linq,C#,Linq,我有下面的XML和通过ID的查询,如何获得父层次结构 <Child> <Child1 Id="1"> <Child2 Id="2"> <Child3 Id="3"> <Child4 Id="4"> <Child5 Id="5"/> <Child6 Id="6"/
<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查找父元素,那么如何获得具有层次结构的以下输出
<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 ;)
}
stringxml=@”
";
TextReader tr=新的StringReader(xml);
XDocument doc=XDocument.Load(tr);
可数myList=
从文件中的el.subjects()开始
其中(字符串)el.Attribute(“Id”)==“4”//here任意
选择el;
//以某种方式选择你的英雄元素
XElement hero=myList.FirstOrDefault();
foreach(hero.祖先()中的XElement祖先)
{
Console.WriteLine(祖先.Name);//在单独的文档中重建树,我打印;)
}
要搜索树中的每个元素,请使用select查询(不带where子句)迭代检索节点,并为每个元素调用foreach。在Linq To XML中,有一个在该节点上调用的方法 返回包含此元素的元素集合,以及 这个元素的祖先 但它不会按照您希望的方式转换XML树 你想要的是:
- 对于给定元素,查找父元素
- 从父元素中删除除给定元素之外的所有元素
- 从给定元素中删除所有元素
XDocument doc=XDocument.Parse(“”);
//例如,查找ID为4的元素
XElement el=doc.subjects().First(el=>el.Attribute(“Id”).Value==“4”);
el.RemoveNodes();
XElement parent=el.parent;
parent.RemoveNodes();
添加(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。根据提供的示例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;
}
stringxml=
@"
";
var doc=XDocument.Parse(xml);
//假设每个节点都有一个Id属性
//将有一个值为4的Id
//否则将引发异常。
XElement el=doc.Root.subjects().First(x=>x.Attribute(“Id”).Value==“4”);
//讨论所有子节点
el.RemoveNodes();
//走到树上寻找父母;当
//父节点为null,则当前节点为
//最顶端的父母。
while(true)
{
如果(el.Parent==null)
{
打破
}
el=el.父母;
}
您尝试过什么吗?我正在尝试,但到目前为止没有成功。这个问题似乎更适合递归算法,而不是linq。对于您的情况,我不知道在我的真实示例中它在哪个级别包含id。无论如何,感谢您在我的示例中的响应,部分并不重要,它只是说明如何获得给定的元素。我将编辑答案以指出这一点。
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;
}