예제 #1
0
        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);
        }
예제 #2
0
        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);
                }
            }
        }