我有一個充滿序列化對象的審計列表,我想比較它們並返回差異列表。通過'比較'我的意思是我想返回一個元素的文本已經改變的地方,或者添加了一個節點的地方(所以它不在Xml1中,但它在Xml2中 - 它不會以相反的方式發生)比較XML片段和返回差異
示例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>
的命名空間和名稱/標籤的情況下也不會改變。本示例中所有可以改變的是標籤之間的值以及'CourseHotelLink(它的序列化列表)的數量。
我想要的最終結果是哪個節點已更改的列表 - 舊值和新值。
什麼是比較它們的最佳選擇?我使用.Net 4.0,所以linq是一個選項。我需要能夠進行比較而不必知道所有節點的名稱 - 儘管我只會比較兩個相同類型的對象。我一直在嘗試使用下面的代碼,但我無法設法使其適應於挑選文本中的更改以及額外的節點。
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);
}
}
}
它可能是我的代碼嘗試是英里關閉,有一個更好的方法來做,歡迎任何建議!
EDITTED要添加: 我最終使用了MS Xml Diff工具,下面的代碼生成了一個大的html表格列表,其中兩個xml節點以綠色突出顯示。所以它可能(儘管是瘋狂的)生成html,然後對其進行排序以找到文本'lightgreen'(突出顯示的值),然後執行一些字符串形成以僅顯示更改後的子節點。
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();
看看這篇文章:http://stackoverflow.com/questions/167946/how-will-you-compare-two-xml-documents –
我還沒有弄清楚如何讓MS Diff和Patch採用XML字符串 - 我的XML來自數據庫,我不想每次我想要創建文件o使用它...可能只是我變得密集。 – UglyTeapot
您不需要創建文件,它帶有許多重載比較文件,XmlTextReader或XmlNode –