2012-05-07 32 views
5

Tôi có danh sách kiểm tra đầy đủ các đối tượng được tuần tự hóa và tôi muốn so sánh chúng và trả về danh sách các khác biệt. Bằng cách 'so sánh', tôi muốn quay lại vị trí văn bản cho phần tử đã thay đổi hoặc vị trí nút đã được thêm vào (vì vậy nó không có trong Xml1, nhưng nó nằm trong Xml2- nó sẽ không xảy ra theo cách khác)So sánh các phân đoạn XML và các khác biệt trả về

mẫu xml:

<HotelBookingView xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Id>119</Id> 
    <RoomId>1</RoomId> 
    <ChangeRequested>false</ChangeRequested> 
    <CourseBookings>  
    <CourseHotelLink> 
     <Id>0</Id> 
    </CourseHotelLink> 
</CourseBookings> 
</HotelBookingView> 

các không gian tên và tên/trường hợp các thẻ sẽ không thay đổi. Tất cả những gì có thể thay đổi trong mẫu này là các giá trị giữa các thẻ và số 'CourseHotelLink's (một danh sách được sắp xếp theo thứ tự).

Kết quả cuối cùng tôi muốn là danh sách nút đã thay đổi - giá trị cũ và giá trị mới.

Tùy chọn nào tốt nhất để so sánh chúng? Tôi đang sử dụng. Net 4.0 để linq là một lựa chọn. Tôi cần để có thể làm so sánh mà không nhất thiết phải biết tên của tất cả các nút- mặc dù tôi sẽ chỉ bao giờ so sánh hai đối tượng cùng loại. Tôi đã cố gắng sử dụng mã sau đây, nhưng tôi không thể quản lý để thích ứng với nó để chọn ra các thay đổi trong văn bản cũng như các nút bổ sung.

XmlDocument Xml1 = new XmlDocument(); 
XmlDocument Xml2 = new XmlDocument(); 
Xml1.LoadXml(list[1].Changes); 
Xml2.LoadXml(list[2].Changes); 
foreach (XmlNode chNode in Xml2.ChildNodes) 
{ 
    CompareLower(chNode); 
} 

protected void CompareLower(XmlNode aNode) 
{ 
    foreach (XmlNode chlNode in aNode.ChildNodes) 
    { 
     string Path = CreatePath(chlNode); 
     if (chlNode.Name == "#text") 
     { 
      //all my efforts at comparing text have failed 
      continue; 
     } 
     if (Xml1.SelectNodes(Path).Count == 0) 
     { 
      XmlNode TempNode = Xml1.ImportNode(chlNode, true); 
      //node didn't used to exist, this works- though doesn't return values 
      str = str + "New Node: " + TempNode.Name + ": " + TempNode.Value; 
     } 
     else 
     { 
      CompareLower(chlNode); 
     } 
    } 
} 

của nó có khả năng nỗ lực mã của tôi là dặm ngoài khơi và có một cách tốt hơn nhiều việc phải làm, bất cứ đề nghị chào đón!

EDITTED để thêm: Tôi đã kết thúc bằng công cụ MS Xml Diff, đoạn mã sau tạo danh sách bảng html lớn của hai nút xml, với sự khác biệt được đánh dấu bằng màu xanh lục. Vì vậy, nó có thể (mặc dù điên) để sản xuất html, sau đó sắp xếp thông qua nó để tìm văn bản 'lightgreen' (giá trị được đánh dấu), sau đó thực hiện một số hình dạng chuỗi để chỉ hiển thị nút con đã thay đổi.

var node1 = XElement.Parse("Xml string 1 here").CreateReader(); 
var node2 = XElement.Parse("Xml string 2 here").CreateReader(); 

MemoryStream diffgram = new MemoryStream(); 
XmlTextWriter diffgramWriter = new XmlTextWriter(new StreamWriter(diffgram)); 

XmlDiff xmlDiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder); 
xmlDiff.Algorithm = XmlDiffAlgorithm.Fast; 
xmlDiff.Compare(node1, node2,diffgramWriter); 

diffgram.Seek(0, SeekOrigin.Begin); 
XmlDiffView xmlDiffView = new Microsoft.XmlDiffPatch.XmlDiffView(); 
StringBuilder sb = new StringBuilder(); 
TextWriter resultHtml = new StringWriter(sb); 
xmlDiffView.Load("Xml string 1", new XmlTextReader(diffgram)); 

xmlDiffView.GetHtml(resultHtml); 
resultHtml.Close(); 
+1

Hãy xem bài này: http://stackoverflow.com/question/167946/how-would-bạn-so sánh-hai-xml-documents –

+0

Tôi chưa biết làm thế nào để có được MS Diff và Patch để lấy các chuỗi XML - XML ​​của tôi xuất phát từ một cơ sở dữ liệu và tôi không muốn phải tạo tệp mỗi lần tôi muốn t o sử dụng nó ... Chỉ có thể là tôi dày đặc. – UglyTeapot

+0

Bạn không cần phải tạo tệp, nó đi kèm với nhiều quá tải để so sánh tệp, XmlTextReader hoặc XmlNode –

Trả lời

7

Sử dụng XMlDiff là cách để đi - để chứng minh đây là một số mã hoạt động. Tôi đang sử dụng XML của bạn. Nếu XML khác (hoặc không hợp lệ), thì điều này có thể không hoạt động.

gốc:

var xml1 = @"<HotelBookingView xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> 
<Id>119</Id> 
<RoomId>1</RoomId> 
<ChangeRequested>false</ChangeRequested> 
<CourseBookings>  
    <CourseHotelLink> 
    <Id>0</Id> 
    </CourseHotelLink> 
</CourseBookings> 
</HotelBookingView>"; 

khác nhau Id giá trị trong CourseBookings:

var xml2 = @"<HotelBookingView xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> 
<Id>119</Id> 
<RoomId>1</RoomId> 
<ChangeRequested>false</ChangeRequested> 
<CourseBookings>  
    <CourseHotelLink> 
    <Id>1</Id> 
    </CourseHotelLink> 
</CourseBookings> 
</HotelBookingView>"; 

thấp nỗ lực cách tạo ra các độc giả (thay đổi để XDocument nếu cần):

var node1 = XElement.Parse(xml1).CreateReader(); 
var node2 = XElement.Parse(xml2).CreateReader(); 

Chuẩn bị kết quả writer:

var result = new XDocument(); 
var writer = result.CreateWriter(); 

Làm diff:

var diff = new Microsoft.XmlDiffPatch.XmlDiff();  
diff.Compare(node1, node2, writer); 
writer.Flush(); writer.Close(); 

result hiện nay là một XDocument có chứa một bản tóm tắt của sự khác biệt:

<xd:xmldiff version="1.0" srcDocHash="14506386314386767543" options="None" fragments="no" xmlns:xd="http://schemas.microsoft.com/xmltools/2002/xmldiff"> 
    <xd:node match="1"> 
    <xd:node match="4"> 
     <xd:node match="1"> 
     <xd:node match="1"> 
      <xd:change match="1">1</xd:change> 
     </xd:node> 
     </xd:node> 
    </xd:node> 
    </xd:node> 
</xd:xmldiff> 
+0

Điều đó có hiệu quả, cảm ơn bạn! Vì vậy, tôi chỉ cần phân tích các diffgram để làm cho nó có thể hiển thị những thứ như 'CourseBookings Id là 0, bây giờ 1', mà nên được vui vẻ! – UglyTeapot

+0

Đừng quên chấp nhận nếu nó trả lời câu hỏi gốc :-) Có rất nhiều thông tin về cách diễn giải sự trở lại từ 'xmldiff'. – yamen

+0

Được chấp nhận, cảm ơn! Và .. có những ví dụ về cách giải thích diffgrams để chỉ hiển thị sự khác biệt? Google-fu yếu của tôi không tìm thấy bất kỳ điều gì – UglyTeapot

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