2011-10-11 41 views
12

Tất cả các giải pháp mà tôi đã gặp phải liên quan đến việc hợp nhất các tài liệu XML không thực hiện được những gì tôi mong muốn. Hãy để tôi giải thích:Việc hợp nhất các tài liệu xml

XML Tài liệu 1:

<?xml version="1.0" encoding="utf-8" ?> 
<a> 
    <b title="Original Section"> 
     <b title="Original Child Section"></b> 
     <b title="Original Child Section 2"></b> 
    </b> 
</a> 

XML Document 2:

<?xml version="1.0" encoding="utf-8" ?> 
<a> 
    <b title="New Section"> 
     <b title="New Child Section"></b> 
    </b> 
    <b title="Original Section"> 
     <b title="Original Child Section"> 
      <b title="New Child For Old Section"></b> 
     </b> 
    </b>  
</a> 

Into một doc thức như thế này:

<?xml version="1.0" encoding="utf-8" ?> 
<a> 
    <b title="Original Section"> 
     <b title="Original Child Section"> 
      <b title="New Child For Old Section"></b> 
     </b> 
     <b title="Original Child Section 2"></b> 
    </b>  
    <b title="New Section"> 
     <b title="New Child Section"></b> 
    </b> 
</a> 

Các tài liệu cũng tương tự như trong nội dung , nhưng có thể có số lượng nút con tùy ý. Tôi cũng muốn loại bỏ các bản sao. Tôi xem xét các bản sao là các phần tử có cùng thuộc tính (dựa trên tên thuộc tính và giá trị). Có ai nhìn thấy một ví dụ làm việc của việc thực hiện này? Tôi có thể hình dung làm thế nào tôi sẽ viết nó bằng cách sử dụng một số vòng và một chút đệ quy, nhưng với tôi, mà chỉ có vẻ không phải là cách tốt nhất để hoàn thành những gì tôi muốn :)

Chúc mừng và cảm ơn trước!

* EDIT *

Kể từ sự đồng thuận là các vòng lặp và đệ quy là phải, những gì sẽ là cách thanh lịch và hiệu quả nhất để thực hiện điều này? Tôi cho rằng một câu hỏi cơ bản khác cho vấn đề này là cách tốt nhất để so sánh các nút khi bạn lặp lại là gì?

+2

Tôi đã triển khai một cái gì đó như thế này cho khách hàng. Về cơ bản nó hoạt động theo cách bạn sẽ thực hiện nó: Sử dụng các vòng lặp và đệ quy. –

+2

+1 cho ví dụ đẹp –

+0

Tôi đồng ý với @DanielHilgarth. Lặp lại và đệ quy về cơ bản là cách đơn giản nhất để thực hiện việc này. – Kian

Trả lời

1

Cuối cùng, mọi giải pháp cho vấn đề này sẽ đun sôi xuống các vòng lặp và/hoặc đệ quy. Bạn đang nói lý thuyết tập hợp cơ bản và LINQ có thể hữu ích cho việc chưng cất quá trình, nhưng cuối cùng nó sẽ lặp lại trên cả hai tập hợp và kết hợp các kết quả.

+0

Đó là những gì tôi nghĩ. Sau đó, tôi cho rằng tôi nên sửa đổi câu hỏi của mình để yêu cầu giải pháp thanh lịch và hiệu quả nhất cho vấn đề này. – nokturnal

1

Tôi muốn viết một IEqualityComparer chỉ định thời điểm hai nút là 'đối sánh' - tức là đặt quy tắc kết hợp tiêu đề.

class XElementComparer : IEqualityComparer<XElement> 
{ 
    public bool Equals(XElement x, XElement y) 
    { 
     var xTitle = x.Attribute("title"); 
     var yTitle = y.Attribute("title"); 

     if (xTitle == null || yTitle == null) return false; 

     return xTitle.Value == yTitle.Value; 
    } 

    public int GetHashCode(XElement obj) 
    { 
     return base.GetHashCode(); 
    } 
} 

Sau đó viết một phương pháp đệ quy để rà soát thông qua XML của bạn, hợp nhất các nút khớp với so sánh.

private XElement Merge(XElement node1, XElement node2) 
{ 
    // trivial cases 
    if (node1 == null) return node2; 
    if (node2 == null) return node1; 

    var elements1 = node1.Elements(); 
    var elements2 = node2.Elements(); 

    // create a merged root 
    var result = new XElement(node1.Name, node1.Attribute("title")); 

    var comparer = new XElementComparer(); 
    var mergedNodes = elements1.Union(elements2, comparer).ToList(); 

    // for the union of the elements, insert their merge values 
    foreach (var title in mergedNodes) 
    { 
     var child1 = elements1.SingleOrDefault(e => comparer.Equals(e, title)); 
     var child2 = elements2.SingleOrDefault(e => comparer.Equals(e, title)); 

     result.Add(Merge(child1, child2)); 
    } 

    return result; 
} 
+0

Tôi biết các tên biến là một chút naff và tôi nên đã thực hiện đúng 'GetHashCode', nhưng những điều cơ bản là có. –

+0

Điều này có vẻ rất hứa hẹn. Đó chính xác là cách tôi tiếp cận vấn đề nhưng thông minh hơn rất nhiều :) Hãy để tôi gây rối với nó và xem những gì tôi có thể nghĩ ra – nokturnal

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