2013-05-21 98 views
0

我有以下XML和查询通过ID,如何获取父层次选择父基于XML的子元素(整个层次)元素的值LINQ

<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> 

在此先感谢。

+0

你尝试过什么吗? – polkduran

+0

我正在努力,但至今没有成功。 –

+0

这个问题似乎比linq更适合递归算法。 – GameAlchemist

回答

0

假设你希望在一个节点父树:

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 ;) 
} 

要搜索你的树迭代的每一个元素检索与选择查询节点,而在where子句,并呼吁每个元素的foreach。

0

在LINQ到XML有一个上该XElement

返回包含该元素的元素,并且该元素的 祖先的集合称为AncestorsAndSelf方法。

但它不会按照您想要的方式转换您的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,最后一个还删除属性。
  • 也从所选元素中删除节点。
+0

对于你的情况,我不知道它在哪个级别包含我的真实例子中的id。无论如何感谢回复 –

+0

在我的例子中,这部分并不重要,它只是说明如何获得给定的元素。我将编辑答案来指出。 – polkduran

-1

我发现下面的方式

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。

0

根据所提供,你可以走了树寻父节点,一旦你找到了节点有问题的样本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; 
} 
0

下面的答案救了我的一天......谢谢

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); 
    }