2009-08-04 24 views
17
Dim xml = <Root> 
      <Parent id="1"> 
       <Child>Thomas</Child> 
      </Parent> 
      <Parent id="2"> 
       <Child>Tim</Child> 
       <Child>Jamie</Child> 
      </Parent> 
      </Root> 

Dim parents = xml.Elements 

Trong trường hợp này, children bao gồm tất cả các phần tử Gốc và tất cả các phần tử Con. Cách tốt nhất để lấy chỉ là hậu duệ trực tiếp của <Root>?LINQ to XML: làm cách nào để tôi chỉ nhận được con cháu trực tiếp của XElement?

Tôi có nên viết truy vấn LINQ để chọn các phần tử mà cha mẹ = <Root> không? Hoặc là có một số phương pháp được xây dựng trong tôi là mất tích mà có thể nhận được điều này cho tôi?

EDIT: Tôi đã có một số nhầm lẫn giữa XElement.ElementsXElement.Descendants. Như Ruben Bartelink đã chỉ ra, XElement.Elements sẽ cho tôi biết chính xác những gì tôi đang tìm kiếm.

+0

Bạn có thể chỉnh sửa trong câu thần chú thực tế mà bạn đã sử dụng không? BTW xin vui lòng tải LINQPAd và thử nó - tuyệt vời của nó để thử nghiệm các công cụ như thế này. Xem các ví dụ tại http://www.dimecasts.net/Casts/ByTag/LinqPad –

Trả lời

17

tóm tắt Exec - bạn muốn:

xml.Elements.Select(function(element) new XElement(element.Name,element.Attributes)) 

câu trả lời đầu tiên:

XElement.Descendants, hoặc là nó một câu hỏi lừa? : P There's an example of usage of Descendants here

câu trả lời Revised, nhờ Tormod - một cái gì đó đã cảm thấy sai !:

Elements cung cấp cho hậu duệ trực tiếp, như bạn đang tìm kiếm. Con cháu cung cấp cho hệ thống phân cấp đầy đủ [như bạn đang cáo buộc Elements]. .! (Ví dụ tôi liên kết với làm rõ này Xin lỗi cho sự nhầm lẫn

Vì vậy, cuối cùng, những gì bạn đang tìm kiếm là (thời gian này trong VB):

Dim xml = <Root> 
     <Parent id="1"> 
      <Child>Thomas</Child> 
     </Parent> 
     <Parent id="2"> 
      <Child>Tim</Child> 
      <Child>Jamie</Child> 
     </Parent> 
     </Root> 

REM All nodes two levels down in the hierarchy 
Dim level2Nodes = xml.Elements.SelectMany(function(element) element.Elements) 
level2Nodes.Dump 

REM All Child nodes, no matter where they are: 
Dim children = xml.Descendants("Child") 

Mỗi trong số đó sẽ mang lại bạn 3 `` `yếu tố vì những lý do khác nhau như trình bày trong REMS

(Dán trên trực tiếp vào LINQPad trong chế độ tuyên bố VB)

bây giờ tôi thấy những gì có thể gây nhầm lẫn bạn -. khi bạn sử dụng các yếu tố và tìm kiếm tại nó trong một visualiser, bạn vẫn còn nhìn thấy những đứa trẻ: -

Dim parents = xml.Elements 

Nếu bạn chỉ muốn những cái tên thực tế, bạn có thể sử dụng một cái gì đó như:

Dim parentNames = xml.Elements.Select(function(element) element.Name) 

Lưu ý rằng trong mỗi trường hợp này, bạn đang nhận được hai kết quả.

Nếu bạn thực sự muốn loại bỏ các trẻ em thất, bạn muốn:

Dim parentElements = xml.Elements.Select(function(element) new XElement(element.Name,element.Attributes)) 

Bạn có thể mở rộng câu hỏi của bạn để hiển thị những gì bạn đang thực sự tìm kiếm?

+3

Phương thức Con cháu() là tất cả các hậu duệ, chứ không chỉ là hậu duệ trực tiếp. Trong trường hợp này, con cháu của "root" sẽ bao gồm tất cả các phần tử con. – Tormod

+0

@Tormod, bạn chắc chắn? Xem ví dụ? Nếu không, sự khác biệt giữa con cháu và yếu tố là gì? –

+0

@Tormod, mea culpa, chỉnh sửa! –

-1

Tại sao không sử dụng XPath?

Dim myXML As var = New XmlDocument() 
myXML.Load(myXML.xml) 

For Each node As XmlNode In myXML.SelectNodes("//") 
    Dim myVar As var = node.SelectSingleNode("Parent").InnerText 
Next 

Thực hiện điều này bằng một chút muối - Tôi vừa chuyển đổi từ C# sang VB.

+0

XLinq thực hiện nó khá gọn gàng như [khi một người vượt qua phạm vi sử dụng phương pháp nào: P] –

+1

Đủ công bằng: P Tôi sẽ phải xem xét, tôi đoán XPath đang trở nên lạc hậu nếu bạn đang di chuyển vào XLinq! –

0

Nếu tất cả hậu duệ trực tiếp có cùng tên phần tử đã biết và tên phần tử này không thể xuất hiện ở cấp độ khác, bạn có thể sử dụng xml.Descendants ("Parent").

15

XElement.Elements lấy tập hợp các phần tử con. Ví dụ:

var s = @"<root> 
      <e1> 
       <e2> 
       </e2> 
      </e1> 
      <e1> 
       <e2> 
       </e2> 
      </e1> 
      <e1> 
       <e2> 
       </e2> 
      </e1> 
      </root>"; 

var doc = XElement.Load(new StringReader(s)); 

Console.WriteLine(doc.Elements().Count()); // 3 
Console.WriteLine(doc.Descendants().Count()); //6 
2

Sử dụng LINQ chúng tôi có thể làm điều đó.

string s = "<Root><Parent id=\"1\"><Child>Thomas</Child></Parent><Parent id=\"2\"><Child>Tim</Child><Child>Jamie</Child></Parent></Root>"; 
XDocument xdoc = XDocument.Parse(s); 
foreach (XElement DirectChild in xdoc.Descendants().Where(child => child.Parent == xdoc.Root)) 
{ 
//Do stuff here 
} 

Hy vọng điều này sẽ hữu ích. Cảm ơn bạn.

Các vấn đề liên quan