0

我有以下 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 找出父元素,如何通过层次结构获得以下输出。

<Child>
    <Child1 Id="1">
        <Child2 Id="2">
            <Child3 Id="3">
                <Child4 Id="4"/>
            </Child3>
        </Child2>
    </Child1>
</Child>

提前致谢。

4

4 回答 4

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 子句的 select 查询检索节点,并为每个元素调用 foreach。

于 2013-05-21T13:10:03.297 回答
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;
}
于 2013-05-21T17:31:02.273 回答
0

在 Linq to XML 中有一个方法调用AncestorsAndSelfXElement

返回包含此元素的元素的集合,以及此元素的祖先。

但它不会按照您想要的方式转换您的 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,最后一个也删除属性。
  • 也从所选元素中删除节点。
于 2013-05-21T13:14:07.350 回答
-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。

于 2013-05-21T16:58:57.033 回答