2013-01-15 34 views
15

Tại thời điểm này, tôi đang quản lý một phần mềm có nhiều tệp cấu hình XML. Khi một phiên bản phần mềm mới được phát hành, đôi khi các tệp cấu hình cơ bản thay đổi, chúng tôi hiện đang có phần mềm gọi KDiff khi khởi động. Nếu phát hiện thay đổi, nó sẽ nhắc người dùng chọn các thay đổi.Diff/XML có lập trình trong C#

Vấn đề với phương pháp này là KDiff là một so sánh chương trình dòng và không nhận thức được đường lối của XML (như nút, vv)

Lý tưởng nhất, tôi muốn lập trình làm việc với một thư viện trong C# (vì chúng ta là một cửa hàng MS) có thể Diff hai tệp XML: XML nguồn và XML hiện tại.

Và sau đó Merge hai cùng sử dụng một vài quy tắc đơn giản:

  1. Nếu công tác XML hiện tại có một nút rằng XML Nguồn không, loại bỏ nó.
  2. Nếu XML nguồn có nút mà XML hoạt động hiện tại không thêm, hãy thêm nó.
  3. Nếu cả hai đều có cùng một nút và giá trị khác nhau, hãy ưu tiên giá trị của XML nguồn, trừ khi giá trị của XML nguồn được đặt thành "UseExistingValue".

Ví dụ, đây là "Source" XML:

<Configuration> 
    <Items> 
    <Item Id="1" Position="true"> 
     <Location X="UseExistingValue" Y="UseExistingValue" Z="UseExistingValue" /> 

     <Something/> 
     <SomethingElse/> 
    </Item> 
    </Items> 
</Configuration> 

Và đây là "hiện tại làm việc" XML:

<Configuration> 
    <Items> 
    <Item Id="1" Position="false"> 
     <Location X="123" Y="234" Z="345" /> 
     <Another/> 
     <Something/> 

    </Item> 
    </Items> 
</Configuration> 

Và phiên bản sáp nhập sẽ như thế nào:

<Configuration> 
    <Items> 
    <Item Id="1" Position="true"> 
     <Location X="123" Y="234" Z="345" /> 

     <Something/> 
     <SomethingElse/> 
    </Item> 
    </Items> 
</Configuration> 

Tôi đã xem số MS XML Diff and Patch Tool và nó là defini hợp nhất các tệp với nhau, nhưng không cho phép các quy tắc có lập trình mà tôi muốn xác định.

XMLUnit for Java devs có vẻ đầy hứa hẹn, nhưng phiên bản .NET của nó dường như kém phát triển, điều này thật không may.

Bất kỳ ai cũng có bất kỳ đề xuất nào về công cụ Diff/Merge XML có thể viết và/hoặc thư viện .NET (trả phí hoặc miễn phí)?

Cảm ơn.

Trả lời

19

Sau một vài ngày lộn xộn xung quanh, tôi đã tìm thấy một giải pháp mà tôi nghĩ là phù hợp với mình. Có lẽ nó cũng có thể làm việc cho những người khác.

The MS XML Diff and Patch tool là một lựa chọn khả thi. Khi bạn Diff tập tin đầu tiên chống lại tập tin thứ hai nó tạo ra một XML "DiffGram" liệt kê những gì thay đổi nó phát hiện giữa hai tập tin XML.

Để xử lý tất cả 3 quy tắc mà tôi liệt kê ở trên, tôi Diff'd hai tệp theo một hướng, sau đó mở tệp DiffGram bằng LINQ-to-XML và xóa tất cả các dòng "Thêm" và "Xóa" .

XNamespace xd = "http://schemas.microsoft.com/xmltools/2002/xmldiff"; 
var doc = XDocument.Load(_diffGramFile); 
doc.Root.DescendantsAndSelf(xd + "add").Remove(); 
doc.Root.DescendantsAndSelf(xd + "remove").Remove(); 

Sau đó, tôi vá (sáp nhập) lược đồ đã chỉnh sửa này đối với tệp đầu tiên và tạo tệp tạm thời được sáp nhập một phần. Việc này sẽ xử lý Quy tắc 1 và 2.

Tiếp theo, tôi Khác biệt tệp được hợp nhất một phần với tệp đầu tiên được sử dụng.Sau đó mở DiffGram mới và xóa tất cả các tham chiếu Thay đổi thành "UseExistingValue".

var newdoc = XDocument.Load(_diffGramFile); 
newdoc.Root.DescendantsAndSelf(xd + "change") 
     .Where(x => x.Value == "UseExistingValue").Remove(); 

Và đã sáp nhập DiffGram đã chỉnh sửa này với tệp được hợp nhất một phần để xử lý Quy tắc 3. Sau đó, tạo XML cuối cùng được hợp nhất theo các quy tắc được xác định ở trên.

Hy vọng điều này có thể giúp đỡ người khác.

GỢI Ý: Sau khi cài đặt thư viện XmlDiffPatch, các XmlDiffPatch DLL có thể được tìm thấy trong C: \ Windows \ lắp ráp \ GAC \ XmlDiffPatch \ 1.0.8.28__b03f5f7f11d50a3a \ XmlDiffPatch.dll

+13

Để cài đặt XMLDiffPatch từ NuGet, xem http: //www.nuget.org/packages/XMLDiffPatch/ – Contango