private static XDiffItem CreateNew(XDiffMatch xd) { var newest = new XElement(xd.ns.First()); foreach (XElement source in xd.ns.Skip(1)) { foreach (XAttribute attribute in source.Attributes()) { if (attribute.Name.LocalName.StartsWith("set-")) { newest.SetAttributeValue(attribute.Name.LocalName.Substring(4), attribute.Value); } else { newest.SetAttributeValue(attribute.Name, attribute.Value); } } if (!string.IsNullOrWhiteSpace(source.Value)) { newest.Value = source.Value; } } var item = new XDiffItem { Action = XDiffAction.CreateElement, NewestElement = newest }; return(item); }
private static IEnumerable <XDiffItem> ProcessCollector(XDiffMatch xd, XElement create_collector, XDiffAction action) { var len = create_collector.Attributes().Count(); if (len != 0) { if (len == 1) { yield return (new XDiffItem { Action = action, BasisElement = xd.b, NewestAttribute = create_collector.Attributes().First() }); } else { yield return(new XDiffItem { Action = action, BasisElement = xd.b, NewestElement = create_collector }); } } }
private IEnumerable <XDiffItem> CreateDiffItems(XDiffMatch xd) { if (null == xd.b && _options.IncludeActions.HasFlag(XDiffAction.CreateElement)) { yield return(CreateNew(xd)); } else if (null != xd.b && 0 == xd.ns.Length && _options.IncludeActions.HasFlag(XDiffAction.DeleteElement)) { yield return(new XDiffItem { Action = XDiffAction.DeleteElement, BasisElement = xd.b }); } else if (null != xd.b && 0 != xd.ns.Length) { if (_options.IncludeActions.HasFlag(XDiffAction.ChangeAttribute | XDiffAction.ChangeElement)) { foreach (XDiffItem xDiffItem in GetDifference(xd)) { yield return(xDiffItem); } } } }
private IEnumerable <XDiffItem> GetDifference(XDiffMatch xd) { var newest = new XElement(xd.ns.First()); if (1 != xd.ns.Length) { foreach (XElement source in xd.ns.Skip(1)) { foreach (XAttribute attribute in source.Attributes()) { if (attribute.Name.LocalName.StartsWith("set-")) { newest.SetAttributeValue(attribute.Name.LocalName.Substring(4), attribute.Value); } else { newest.SetAttributeValue(attribute.Name, attribute.Value); } } if (!string.IsNullOrWhiteSpace(source.Value)) { newest.Value = source.Value; } } } if (_options.IncludeActions.HasFlag(XDiffAction.ChangeElement)) { string valb = string.Join(Environment.NewLine, xd.b.Nodes().Except(xd.b.Elements().Where(_ => null != _.Attribute("__parent")))); string valn = string.Join(Environment.NewLine, newest.Nodes().Except(newest.Elements().Where(_ => null != _.Attribute("__parent")))); if (valb != valn) { yield return(new XDiffItem { Action = XDiffAction.ChangeElement, BasisElement = xd.b, NewValue = valn }); } } if (_options.IncludeActions.HasFlag(XDiffAction.DeleteAttribute) && !_options.TreatDeleteAttributesAsChanges) { foreach (XAttribute attribute in xd.b.Attributes()) { if (attribute.Name.LocalName == "id") { continue; } if (attribute.Name.LocalName == "code") { continue; } if (attribute.Name.LocalName == "__parent") { continue; } if (null == newest.Attribute(attribute.Name)) { if (_options.TreatDeleteAttributesAsChanges) { bool isnumber = attribute.Value == "0" || attribute.Value.ToDecimal(true) != 0; var val = ""; if (isnumber) { val = "0"; } yield return (new XDiffItem { Action = XDiffAction.ChangeAttribute, BasisElement = xd.b, NewestAttribute = new XAttribute(attribute.Name, val) }); } else { yield return(new XDiffItem { Action = XDiffAction.DeleteAttribute, BasisElement = xd.b, BasisAttribute = attribute } ); } } } } if (_options.IncludeActions.HasFlag(XDiffAction.ChangeAttribute | XDiffAction.CreateAttribute) || _options.TreatDeleteAttributesAsChanges) { XElement create_collector = (_options.MergeAttributeChanges && !_options.TreatNewAttributesAsChanges) ? new XElement("insert") : null; XElement update_collector = (_options.MergeAttributeChanges) ? new XElement("update") : null; foreach (XAttribute attribute in newest.Attributes()) { if (attribute.Name.LocalName == "id" && !_options.ChangeIds) { continue; } if (attribute.Name.LocalName == "code" && !_options.ChangeIds) { continue; } if (attribute.Name.LocalName == "__parent") { continue; } XAttribute a = attribute; if (a.Name.LocalName.StartsWith("set-")) { a = new XAttribute(a.Name.LocalName.Substring(4), a.Value); } if (null == xd.b.Attribute(a.Name) && (_options.IncludeActions.HasFlag(XDiffAction.CreateAttribute) || _options.TreatNewAttributesAsChanges || _options.TreatDeleteAttributesAsChanges)) { if (_options.MergeAttributeChanges) { (_options.TreatNewAttributesAsChanges?update_collector:create_collector).SetAttributeValue(a.Name, a.Value); } else { yield return (new XDiffItem { Action = _options.TreatNewAttributesAsChanges ? XDiffAction.ChangeAttribute : XDiffAction.CreateAttribute, BasisElement = xd.b, NewestAttribute = a }); } } else if (attribute.Value != xd.b.Attr(a.Name.LocalName) && _options.IncludeActions.HasFlag(XDiffAction.ChangeAttribute)) { if (_options.MergeAttributeChanges) { update_collector.SetAttributeValue(a.Name, a.Value); } else { yield return(new XDiffItem { Action = XDiffAction.ChangeAttribute, BasisElement = xd.b, NewestAttribute = a }); } } } if (_options.TreatDeleteAttributesAsChanges) { foreach (var oa in xd.b.Attributes()) { if (null == newest.Attribute(oa.Name)) { var bval = oa.Value; var isnumber = bval == "0" || bval.ToDecimal(true) != 0; var nval = isnumber ? "0" : ""; if (_options.MergeAttributeChanges) { update_collector.SetAttributeValue(oa.Name, nval); } else { yield return(new XDiffItem { Action = XDiffAction.ChangeAttribute, BasisElement = xd.b, NewestAttribute = new XAttribute(oa.Name, nval) }); } } } } if (null != create_collector) { foreach (var i in ProcessCollector(xd, create_collector, XDiffAction.CreateAttribute)) { yield return(i); } } if (null != update_collector) { foreach (var i in ProcessCollector(xd, update_collector, XDiffAction.ChangeAttribute)) { yield return(i); } } } if (_options.IsHierarchy && _options.IncludeActions.HasFlag(XDiffAction.ChangeHierarchyPosition)) { XAttribute newparent = newest.Attribute("__parent"); XAttribute oldparent = xd.b.Attribute("__parent"); if (null == newparent && null == oldparent) { } else if (null == newparent && null != oldparent) { //move to root yield return(new XDiffItem { Action = XDiffAction.ChangeHierarchyPosition, BasisElement = xd.b }); } else if ((null == oldparent && null != newparent) || (oldparent.Value != newparent.Value)) { yield return (new XDiffItem { Action = XDiffAction.ChangeHierarchyPosition, BasisElement = xd.b, NewValue = newparent.Value }); } } if (_options.IncludeActions.HasFlag(XDiffAction.RenameElement)) { if (xd.b.Name.LocalName != newest.Name.LocalName) { yield return (new XDiffItem { Action = XDiffAction.RenameElement, BasisElement = xd.b, NewValue = newest.Name.LocalName }); } } }