2011-10-25 26 views
6

Tôi có tệp xml trả về tập hợp các phần tử duy nhất theo giá trị thuộc tính. Điều này trình bày một vấn đề, vì tôi không thể chọn một nút theo tên của nó:LINQ to XML chọn căn cứ nút trên giá trị thuộc tính

<doc> 
    <float name="score">1.2873721</float> 
    <arr name="2_category"> 
     <long>3021</long> 
    </arr> 
    <arr name="ATR_FamilyName"> 
     <str>Some Cookbook </str> 
    </arr> 
    <arr name="ATR_IsFamily"> 
     <str>0</str> 
    </arr> 
    <arr name="ATR_SellPrice"> 
     <str>49.95</str> 
    </arr> 
    <arr name="ATR_VendorId"> 
     <str>ABC</str> 
    </arr> 
    <arr name="ATR_VendorName"> 
     <str>WROX</str> 
    </arr>  
</doc> 

Tôi đang sử dụng LINQ để điền vào một lớp "Sản phẩm". Tôi có thể chọn các yếu tố theo vị trí, tuy nhiên điều này sẽ trở thành một vấn đề nếu nút không tồn tại. Có cách nào để chọn một nút dựa trên giá trị của thuộc tính của nó không? Trong ví dụ dưới đây, tôi có thể lấy nút arr nếu thuộc tính @name = "ATR_FamilyName" không? Trong xpath nó sẽ là:

doc/arr[@name = 'ATR_FamilyName']/str 

đây là LINQ của tôi để truy vấn xml:

var query = from rt in results 
    where (String)rt.Descendants().ElementAt(5).Element("str").Value == "0" 
    select new Product.Product 
      { 
       FamilyName = (String)rt.Descendants().ElementAt(3).Value 
       // doc/arr[@name = 'ATR_FamilyName']/str - select Family Name is arr/@name 'ATR_FamilyName'        
       MorePropertiestoset....        
       }; 

Trả lời

17

Giống như câu trả lời của AS-CII, nhưng không sử dụng biểu thức truy vấn (trừ biểu thức bên ngoài) và với dàn diễn viên cho XAttribute và chọn giá trị phần tử str bên trong loại ẩn danh:

select new Product.Product 
{ 
    FamilyName = rt.Descendants("arr") 
        .Where(x => (string) x.Attribute("name") == "ATR_FamilyName") 
        .Select(x => (string) x.Element("str")) 
        .FirstOrDefault(), 
    MorePropertiesToSet....        
}; 

Lưu ý rằng việc sử dụng một dàn diễn viên cho là kết quả của các cuộc gọi đến Attribute("name") có nghĩa là nếu có bất kỳ yếu tố mà không có thuộc tính, các diễn viên sẽ cho kết quả trong một tham chiếu null (mà isn 't bằng chuỗi chữ). Nếu bạn sử dụng thuộc tính Value, bạn sẽ nhận được một ngoại lệ. Đôi khi một ngoại lệ có thể tốt hơn - nếu điều đó chỉ ra rằng dữ liệu về cơ bản bị hỏng và bạn muốn tìm hiểu về nó thay vì không khớp với giá trị.

(Điều này cũng đúng đối với các diễn viên của XElement-string.)

+0

Cảm ơn Jon - Bạn đóng đinh. Tôi thích câu trả lời nhanh từ mọi người – PhillyNJ

+0

Thx cho lời giải thích về việc đúc, Jon. Tôi đã chạy vào các tình huống mà không phải tất cả các nút có thuộc tính và nó đã ném một ngoại lệ vì tôi đã sử dụng .Giá trị thay vì dàn diễn viên; này fidex nó. –

5

Với LINQ bạn có thể dễ dàng lựa chọn chỉ các nút có một thuộc tính nhất định, như thế này:

var query = from node in results.Descendants("arr") // I believe you could use results.Elements("arr") here 
      where node.Attribute("name").Value == "ATR_FamilyName" 
      select new Product 
      { 
       FamilyName = node.Element("str").Value 
      }; 
2

Sử dụng XElement như thế này:

from rt in results.descendants("<node name>") 
where rt.attribute(attribute name).value == "specified value" 
select rt 

Xin lỗi vì gõ từ điện thoại di động

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