public static IList <ListCompare> TwoWayDiff(string baseXml, string compareXml, out string baseFormatted, out string compareFormatted) { var baseElem = GetFirstItemElem(XElement.Parse(baseXml)); baseElem = baseElem.Parent ?? baseElem; var compareElem = GetFirstItemElem(XElement.Parse(compareXml)); compareElem = compareElem.Parent ?? compareElem; var settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = " "; settings.OmitXmlDeclaration = true; settings.NewLineOnAttributes = false; var baseWriter = new ElementWriter(settings); baseWriter.WriteStartElement(baseElem); var compareWriter = new ElementWriter(settings); compareWriter.WriteStartElement(compareElem); var results = new List <ListCompare>(); if (!baseElem.Elements().Any() || !baseElem.Elements().Any()) { var isDifferent = baseElem.Elements().Any() || baseElem.Elements().Any() || GetKeys(Enumerable.Repeat(baseElem, 1)).Single().Item1 != GetKeys(Enumerable.Repeat(compareElem, 1)).Single().Item1; results.Add(new ListCompare(baseWriter.CurrentLine + 1, compareWriter.CurrentLine + 1) { IsDifferent = isDifferent }); } else { results.Add(new ListCompare(baseWriter.CurrentLine + 1, compareWriter.CurrentLine + 1) { IsDifferent = false }); TwoWayDiff(baseElem, compareElem, baseWriter, compareWriter, results); } baseWriter.WriteEndElement(); baseFormatted = baseWriter.ToString(); compareWriter.WriteEndElement(); compareFormatted = compareWriter.ToString(); return(results); }
private static void TwoWayDiff(XElement baseElem, XElement compareElem, ElementWriter bWriter, ElementWriter cWriter, List <ListCompare> results) { var baseList = GetKeys(baseElem.Elements()); var compareList = GetKeys(compareElem.Elements()); var compares = ListCompare.Create(baseList, compareList, v => v.Item1); // Deal with the relationships of versionable items if (baseElem.Name.LocalName == "Relationships" && !compares.Any(c => c.Base >= 0 && c.Compare >= 0)) { var baseRelateds = baseElem.Elements().Select(e => Tuple.Create(GetRelatedId(e), e)).ToList(); var compareRelateds = compareElem.Elements().Select(e => Tuple.Create(GetRelatedId(e), e)).ToList(); if (!baseRelateds.Any(t => string.IsNullOrEmpty(t.Item1)) && !compareRelateds.Any(t => string.IsNullOrEmpty(t.Item1)) && baseRelateds.Select(t => t.Item1).Distinct().Count() == baseRelateds.Count && compareRelateds.Select(t => t.Item1).Distinct().Count() == compareRelateds.Count) { compares = ListCompare.Create(baseRelateds, compareRelateds, v => v.Item1); } } int start; foreach (var tuple in compares) { if (tuple.Base < 0) { start = cWriter.CurrentLine + 1; cWriter.WriteElement(compareList[tuple.Compare].Item2); results.AddRange(Enumerable.Range(start, cWriter.CurrentLine - start + 1).Select(i => new ListCompare(-1, i))); } else if (tuple.Compare < 0) { start = bWriter.CurrentLine + 1; bWriter.WriteElement(baseList[tuple.Base].Item2); results.AddRange(Enumerable.Range(start, bWriter.CurrentLine - start + 1).Select(i => new ListCompare(i, -1))); } else if (baseList[tuple.Base].Item2.Elements().Any() && compareList[tuple.Compare].Item2.Elements().Any()) { results.Add(new ListCompare(bWriter.CurrentLine + 1, cWriter.CurrentLine + 1) { IsDifferent = false }); bWriter.WriteStartElement(baseList[tuple.Base].Item2); cWriter.WriteStartElement(compareList[tuple.Compare].Item2); TwoWayDiff(baseList[tuple.Base].Item2, compareList[tuple.Compare].Item2, bWriter, cWriter, results); bWriter.WriteEndElement(); cWriter.WriteEndElement(); } else if (baseList[tuple.Base].Item2.Elements().Any() || compareList[tuple.Compare].Item2.Elements().Any() || baseList[tuple.Base].Item2.Value != compareList[tuple.Compare].Item2.Value) { results.Add(new ListCompare(bWriter.CurrentLine + 1, cWriter.CurrentLine + 1) { IsDifferent = true }); for (int i = results.Last().Base; i < bWriter.CurrentLine; i++) { results.Add(new ListCompare(i, -1)); } for (int i = results.Last().Compare; i < cWriter.CurrentLine; i++) { results.Add(new ListCompare(-1, i)); } bWriter.WriteElement(baseList[tuple.Base].Item2); cWriter.WriteElement(compareList[tuple.Compare].Item2); } else { results.Add(new ListCompare(bWriter.CurrentLine + 1, cWriter.CurrentLine + 1)); bWriter.WriteElement(baseList[tuple.Base].Item2); cWriter.WriteElement(compareList[tuple.Compare].Item2); } } }