簡體   English   中英

根據子元素值 LINQ 選擇父 XML(整個層次結構)元素

[英]Select Parent XML(Entire Hierarchy) Elements based on Child element values LINQ

我有以下 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>

提前致謝。

假設您只需要一個節點父樹:

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。

在 Linq to 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 ,最后一個也刪除了屬性。
  • 也從所選元素中刪除節點。

根據提供的示例 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;
}

以下答案挽救了我的生活...謝謝

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

我找到了以下方法

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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM