2008-10-01 21 views
5

Tôi cần thay thế nội dung của nút trong phân cấp XElement khi tên phần tử và tất cả tên và giá trị thuộc tính khớp với phần tử đầu vào . (Nếu không có trận đấu, yếu tố mới có thể được thêm vào.)Tôi cần biểu thức LINQ để tìm một XElement, trong đó tên và thuộc tính khớp với nút đầu vào

Ví dụ, nếu dữ liệu của tôi trông như thế này:

<root> 
    <thing1 a1="a" a2="b">one</thing1> 
    <thing2 a1="a" a2="a">two</thing2> 
    <thing2 a1="a" a3="b">three</thing2> 
    <thing2 a1="a">four</thing2> 
    <thing2 a1="a" a2="b">five</thing2> 
<root> 

Tôi muốn tìm yếu tố cuối cùng khi tôi gọi một phương thức với điều này đầu vào:

<thing2 a1="a" a2="b">new value</thing2> 

Phương pháp này không có phần tử hoặc tên thuộc tính được mã hóa đơn giản - chỉ khớp với dữ liệu nhập vào dữ liệu.

Trả lời

5

này sẽ phù hợp bất kỳ yếu tố được đưa ra với tên thẻ chính xác và thuộc tính cặp tên/giá trị:

public static void ReplaceOrAdd(this XElement source, XElement node) 
{ var q = from x in source.Elements() 
      where x.Name == node.Name 
       && x.Attributes().All 
            (a =>node.Attributes().Any 
            (b =>a.Name==b.Name && a.Value==b.Value)) 
      select x; 

    var n = q.LastOrDefault(); 

    if (n == null) source.Add(node); 
    else n.ReplaceWith(node);            
} 

var root =XElement.Parse(data); 
var newElem=XElement.Parse("<thing2 a1=\"a\" a2=\"b\">new value</thing2>"); 

root.ReplaceOrAdd(newElem); 
+0

Một tối ưu hóa tiềm năng (không chắc chắn cách dữ liệu được lưu trữ nội bộ) sẽ được xác định tên là một cuộc tranh cãi để Elements() thay vì bao gồm nó trong mệnh đề Where. –

+0

Tại sao thay thế toàn bộ phần tử? Bạn có thể không chỉ thay thế giá trị không? – Haroon

+0

Có, trong trường hợp cụ thể này, bạn chỉ có thể đặt thuộc tính 'Giá trị'. –

0

Bạn có thể thực hiện XPathSelectElement với đường dẫn (không báo cho tôi, đến thanh, sẽ dọn sạch vào buổi sáng)/root/thing2 [@ a1 = 'a' và @ a2 = 'b'] và sau đó lấy .LastOrDefault() (XPathSelectElement là một phương thức mở rộng trong system.Linq.Xml).

Điều đó sẽ giúp bạn có được nút bạn muốn thay đổi. Tôi không chắc chắn làm thế nào bạn muốn thay đổi nó, tuy nhiên. Kết quả bạn nhận được là XElement thực tế, vì vậy việc thay đổi nó sẽ thay đổi phần tử cây.

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