XMLDiff无法正确识别差异?

我在这里想念的是什么? XMLDiff是否应关注元素名称并寻求最佳匹配以正确识别以下更改?

一个Helper类,用于在两个XML文件之间进行比较:

public class XMLDiffer { public XDocument Diff(string originalXML, string changedXML) { //http://msdn2.microsoft.com/en-us/library/aa302294.aspx XmlDiff xmlDiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreComments | XmlDiffOptions.IgnoreWhitespace); xmlDiff.Algorithm = XmlDiffAlgorithm.Precise; StringBuilder diffgramStringBuilder = new StringBuilder(); bool xmlComparisonResult = false; using (StringReader legacySr = new StringReader(originalXML), nextgenSr = new StringReader(changedXML)) { using (XmlReader legacyReader = XmlReader.Create(legacySr), nextgenReader = XmlReader.Create(nextgenSr)) { using (StringWriter sw = new StringWriter(diffgramStringBuilder)) { using (XmlWriter diffgramWriter = XmlWriter.Create(sw)) { xmlComparisonResult = xmlDiff.Compare(legacyReader, nextgenReader, diffgramWriter); } } } } XDocument xdoc = XDocument.Parse(diffgramStringBuilder.ToString()); return xdoc; } public string GetChangeHtml(string originalXML, string changedXML) { XmlDiffView view = new XmlDiffView(); var diffgram = Diff(originalXML, changedXML); string ret = ""; using (StringReader legacySr = new StringReader(originalXML), diffGramSr = new StringReader(diffgram.ToString())) { using (XmlReader legacyReader = XmlReader.Create(legacySr), diffgramReader = XmlReader.Create(diffGramSr)) { using (StringWriter sw = new StringWriter()) { view.Load(legacyReader, diffgramReader); view.GetHtml(sw); ret = sw.ToString(); } } } return ret; } } 

有以下测试:

 [TestMethod] public void XMLDiff_AreNotSame_GetChangeHtmlAll() { //Arrange string source = "some textmore textREMOVED"; //Ordering of the generic child nodes is not changed, but it might string target = "some text CHANGEmore textADDITION"; XMLDiffer differ = new XMLDiffer(); //Act var diffview = differ.GetChangeHtml(source, target); //Assert Assert.IsNotNull(diffview); } 

生成以下内容(添加了html和table元素): https : //pste.eu/p/Fm7Z.html

有关库的更多信息: http : //msdn2.microsoft.com/en-us/library/aa302294.aspx

Nuget参考链接: https ://www.nuget.org/packages/XMLDiffPatch/

我最终实现了以下类来进行更改:

 public class XMLComparer : IEqualityComparer { public bool Equals(XNode e1, XNode e2) { if (!(e1 is XElement)) return true; if (!(e2 is XElement)) return false; var el1 = e1 as XElement; var el2 = e2 as XElement; return Tuple.Create(el1.Name, el1.Value).Equals(Tuple.Create(el2.Name, el2.Value)); } public int GetHashCode(XNode n) { if (!(n is XElement)) return 0; var el = n as XElement; return Tuple.Create(el.Name, el.Value).GetHashCode(); } } public class XMLDifference { public bool IsNew { get; set; } public XElement Node { get; set; } } public class XMLDifferenceComparer { public List GetDifferences(string original, string changed) { List ret = new List(); var originalDoc = XDocument.Parse(original); var changedDoc = XDocument.Parse(changed); //Get differences that are present in new xml version var differences = changedDoc.Root.Descendants().Except(originalDoc.Root.Descendants(), new XMLComparer()); ret.AddRange(GetList(differences, true)); //Get differences that have changed since the old xml version var oldValues = originalDoc.Root.Descendants().Except(changedDoc.Root.Descendants(), new XMLComparer()); ret.AddRange(GetList(oldValues, false)); return ret; } private List GetList(IEnumerable nodes, bool isNew) { List ret = new List(); foreach (XNode d in nodes) { var diff = new XMLDifference(); diff.IsNew = isNew; var el = d as XElement; diff.Node = el; ret.Add(diff); } return ret; } } 

这可以识别更改但不是特定于元素,它不能映射确切地更改了哪个元素以及由于缺少每个元素的唯一标识符而导致的元素。

这个解决方案的主要思想来自: https : //gist.github.com/krcourville/6933451