using System.Globalization; namespace Kit.Helpers { using System; using System.Xml; using System.Linq; using System.Collections.Generic; public enum ItemLogTypes { None = 0, Create = 1, Update = 2, Delete = 3, } public class ItemLogGenerator { public object ObjectId { get; set; } public string ObjectType { get; set; } public ItemLogGenerator(object objectId, string objectType) { ObjectId = objectId; ObjectType = objectType; } public List Items { get; set; } = new List(); public ItemLogGenerator Add(ItemLog item) { if (item != null) { Items.Add(new ItemLog(ObjectId, ObjectType, item.Name, item.Title) { Type = item.Type, ValueNew = item.ValueNew, ValueOld = item.ValueOld }); } return this; } public ItemLogGenerator AddRange(IEnumerable items) { if (items.IsNullOrEmpty() == false) { items.ForEach(item => { Items.Add(new ItemLog(ObjectId, ObjectType, item.Name, item.Title) { Type = item.Type, ValueNew = item.ValueNew, ValueOld = item.ValueOld }); }); } return this; } } public class ItemLog { public ItemLogTypes Type { get; set; } public ItemLog(string name, string? title = null) { Type = ItemLogTypes.None; Name = name ?? string.Empty; Title = title ?? string.Empty; } public ItemLog(object objectId, string objectType, string name, string? title = null) : this(name, title) { ObjectId = objectId; ObjectType = objectType ?? string.Empty; } public object ObjectId { get; set; } public string ObjectType { get; set; } public string Name { get; set; } public string Title { get; set; } public string ValueOld { get; set; } public string ValueNew { get; set; } public ItemLog FillType() { bool hasValueOld = string.IsNullOrEmpty(ValueOld) == false; bool hasValueNew = string.IsNullOrEmpty(ValueNew) == false; if (hasValueOld == false && hasValueNew == false) { Type = ItemLogTypes.None; return this; } if (hasValueOld == false && hasValueNew) { Type = ItemLogTypes.Create; return this; } if (hasValueOld && hasValueNew == false) { Type = ItemLogTypes.Delete; return this; } if (ValueOld.Equals(ValueNew) == false) { Type = ItemLogTypes.Update; return this; } Type = ItemLogTypes.None; return this; } } public static class SystemXmlNodeExtensionMethods { private static readonly CultureInfo ci = new CultureInfo("en-US"); public static void RemoveAttribute(this XmlDocument input, string name) { foreach (XmlNode item in input.SelectNodes("//*[@{0}]".ApplyFormat(name))) { item.Attributes.Remove(item.Attributes[name]); } } public static XmlNode SetElementValue(this XmlNode input, string name, string value) { var element = input.SelectSingleNode(name); if (element == null) { element = input.OwnerDocument.CreateElement(name); input.AppendChild(element); } element.InnerText = value; return element; } public static XmlNode SetElementValue(this XmlNode input, string name, DateTime value) { var element = input.SelectSingleNode(name); if (element == null) { element = input.OwnerDocument.CreateElement(name); input.AppendChild(element); } element.InnerText = XmlConvert.ToString(value, XmlDateTimeSerializationMode.RoundtripKind); return element; } public static XmlNode SetElement(this XmlNode input, string name, Object value) { var element = input.SelectSingleNode(name); if (element == null) { element = input.OwnerDocument.CreateElement(name); input.AppendChild(element); } element.InnerText = value.ToString(); return element; } public static XmlNode SetElementCDataValue(this XmlNode input, string name, string value) { var element = input.SelectSingleNode(name); if (element == null) { var root = input.OwnerDocument.CreateElement(name); element = input.OwnerDocument.CreateNode(XmlNodeType.CDATA, name, null); root.AppendChild(element); input.AppendChild(root); } element.InnerText = value; return element; } public static XmlNode SetElementValue(this XmlNode input, string name, decimal value) { return input.SetElementValue(name, value.ToString(System.Globalization.CultureInfo.InvariantCulture)); } public static XmlNode SetElementValue(this XmlNode input, string name, decimal? value, string elementsAfterPostion) { if (value.HasValue) { return input.SetElementNullableValue(name, elementsAfterPostion, value.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)); } else { return input.SetElementNullableValue(name, null); } } public static XmlNode SetElementValue(this XmlNode input, string name, int? value, string elementsAfterPostion) { if (value.HasValue && value != 0) { return input.SetElementNullableValue(name, elementsAfterPostion, value.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)); } else { return input.SetElementNullableValue(name, null); } } private static XmlNode GetElementAfterInsert(XmlNode root, string elementsAfterPostion) { if (!elementsAfterPostion.IsNullOrEmpty()) { var elements = root.SelectNodes(elementsAfterPostion); return elements.Cast().LastOrDefault(); } return null; } public static XmlNode SetElementNullableValue(this XmlNode input, string name, string value) { return input.SetElementNullableValue(name, "", value); } public static XmlNode SetElementNullableValue(this XmlNode input, string name, string elementsAfterPostion, string value) { if (!value.IsNullOrEmpty()) { var element = input.SelectSingleNode(name); if (element != null) { input.RemoveChild(element); } element = input.OwnerDocument.CreateElement(name); var after = GetElementAfterInsert(input, elementsAfterPostion); if (after == null) input.InsertBefore(element, input.FirstChild); else input.InsertAfter(element, after); element.InnerText = value; return element; } else { var child = input.SelectSingleNode(name); if (child != null) input.RemoveChild(child); return null; } } public static XmlNode CreateElement(this XmlNode input, string name) => input.CreateElement(input.OwnerDocument, name); public static XmlNode CreateElement(this XmlNode input, XmlDocument xmlDocument, string name) { //var element = input.SelectSingleNode(name); //if (element == null) //{ var element = xmlDocument.CreateElement(name); input.AppendChild(element); //} return element; } public static XmlAttribute CreateAttributeValue(this XmlNode input, string name, string value) { XmlAttribute element = null; //try { element = input.Attributes[name]; } //catch { if (element == null) { element = input.OwnerDocument.CreateAttribute(name); input.Attributes.Append(element); } element.InnerText = value; } return element; } public static bool HasAttribute(this XmlNode input, string name) { return input.Attributes[name] != null; } public static void SetAttribute(this XmlNode input, string name, Object value) { XmlAttribute element = null; //try { element = input.Attributes[name]; } //catch { } if (element == null) { element = input.OwnerDocument.CreateAttribute(name); input.Attributes.Append(element); } element.InnerText = value.ToString(); } public static void SetAttributeNullable(this XmlNode input, string name, string? value) { if (string.IsNullOrWhiteSpace(value)) { input.RemoveAttribute(name); } else { input.SetAttribute(name, value); } } public static void RemoveAttribute(this XmlNode input, string name) { if (input.Attributes == null || input.Attributes.Count == 0) return; XmlAttribute? element = input.Attributes[name]; if (element == null) return; ((XmlElement)input).RemoveAttribute(name); } public static void SetAttributeValue(this XmlNode input, string name, string value) { XmlAttribute element = null; //try { element = input.Attributes[name]; } //catch { } if (element == null) { element = input.OwnerDocument.CreateAttribute(name); input.Attributes.Append(element); } element.InnerText = value; } public static void SetAttributeValue(this XmlNode input, string name, Guid? value) { XmlAttribute element = null; //try { element = input.Attributes[name]; } //catch { } if (element == null) { element = input.OwnerDocument.CreateAttribute(name); input.Attributes.Append(element); } element.InnerText = value.ToStringOrEmpty(); } public static string GetValueAttribute(this XmlNode input, string name) { return input.GetValueAttribute(name, string.Empty); } public static string GetValueAttribute(this XmlNode input, string name, string empty) { XmlAttribute element = null; //try { if (input == null) return empty; element = input.Attributes[name]; if (element != null) return element.InnerText; else return empty; } //catch //{ // return empty; //} } public static string GetValueAttribute(this XmlNode input, string name, string empty, XmlNamespaceManager namespaces) { XmlNode element = null; //try { if (input == null) return empty; element = input.SelectSingleNode(name, namespaces); if (element != null) return element.InnerText; else return empty; } //catch //{ // return empty; //} } public static string GetValue(this XmlNode input, string name) { return input.GetValue(name, String.Empty); } public static DateTime GetValueDateTime(this XmlNode input, string name) { return XmlConvert.ToDateTime(input.GetValue(name, String.Empty), XmlDateTimeSerializationMode.RoundtripKind); } public static string GetValue(this XmlNode input, string name, string empty) { var element = input.SelectSingleNode(name); if (element == null) return empty; return element.InnerText; } public static string GetValue(this XmlNode input, string name, XmlNamespaceManager namespaces) { return input.GetValue(name, String.Empty, namespaces); } public static string GetValue(this XmlNode input, string name, string empty, XmlNamespaceManager namespaces) { var element = input.SelectSingleNode(name, namespaces); if (element == null) return empty; return element.InnerText; } public static string GetValueCData(this XmlNode input, string name) { return input.GetValueCData(name, string.Empty); } public static string GetValueCData(this XmlNode input, string name, string empty) { var element = input.SelectSingleNode(name); if (element == null) return empty; if (element.FirstChild == null) return element.InnerText; return element.FirstChild.InnerText; } public static DateTime? GetValueDate(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToDateXMLNullable(); } public static DateTime GetValueDate(this XmlNode input, string name, DateTime empty) { return input.GetValue(name, String.Empty).TryParseToDateXMLNullable(empty); } public static short GetValueShort(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToShort(); } public static bool GetValueBool(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToBool(false); } public static bool GetValueBool(this XmlNode input, string name, bool empty) { return input.GetValue(name, String.Empty).TryParseToBool(empty); } public static Int32? GetValueInt32Nulable(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToInt32Nulable(); } public static Int32 GetValueInt32(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToInt32(); } public static Int32 GetValueInt32(this XmlNode input, string name, int empty) { return input.GetValue(name, String.Empty).TryParseToInt32(empty); } public static byte GetValueByte(this XmlNode input, string name, byte empty) { return input.GetValue(name, String.Empty).TryParseToByte(empty); } public static decimal? GetValueDecimal(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToDecimalNulable(); } public static decimal GetValueDecimal(this XmlNode input, string name, decimal empty) { return input.GetValue(name, String.Empty).TryParseToDecimal(empty); } public static Guid GetValueGuid(this XmlNode input, string name, Guid empty) { return input.GetValue(name, String.Empty).TryParseToGuid(empty); } public static Guid GetValueGuid(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToGuid(Guid.Empty); } public static Guid? GetValueGuidNullable(this XmlNode input, string name) { return input.GetValue(name, String.Empty).TryParseToGuidNulable(null); } public static Guid GetValueAttributeGuid(this XmlNode input, string name) { return input.GetValueAttributeGuid(name, null) ?? Guid.Empty; } public static Guid? GetValueAttributeGuid(this XmlNode input, string name, Guid? empty) { return input.GetValueAttribute(name, String.Empty).TryParseToGuidNulable(empty); } public static Guid? GetValueAttributeGuid(this XmlNode input, string name, XmlNamespaceManager namespaces, Guid? empty) { return input.GetValueAttribute(name, String.Empty).TryParseToGuidNulable(empty); } public static int GetValueAttributeInt32(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToInt32(0); } public static int? GetValueAttributeInt32Nullable(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToInt32Nulable(); } public static double GetValueAttributeDouble(this XmlNode input, string name) { return GetValueAttributeDouble(input, name, 0); } public static double GetValueAttributeDouble(this XmlNode input, string name, double @default) { return input.GetValueAttribute(name, String.Empty).TryParseToDouble(@default); } public static double? GetValueAttributeDoubleNullable(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToDoubleNulable(); } public static long GetValueAttributeInt64(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToInt64(0); } public static long? GetValueAttributeInt64Nullable(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToInt64Nulable(); } public static ulong GetValueAttributeUInt64(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToUInt64(0); } public static ulong? GetValueAttributeUInt64Nullable(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToUInt64Nulable(); } public static bool GetValueAttributeBool(this XmlNode input, string name) { return input.GetValueAttribute(name, String.Empty).TryParseToBool(false); } public static bool GetValueAttributeBool(this XmlNode input, string name, bool empty) { return input.GetValueAttribute(name, String.Empty).TryParseToBool(empty); } public static string ToStringXMLShema(this DateTime dt) { if (dt == null) return String.Empty; return dt.ToString("yyyy-MM-ddTHH:mm:ss"); } public static string ToStringXMLShema(this DateTime? dt) { if (dt == null) return String.Empty; return (dt ?? DateTime.UtcNow).ToString("yyyy-MM-ddTHH:mm:ss"); } public static string ToStringSoutXML(this DateTime dt) { if (dt == null) return String.Empty; return dt.ToString("yyyy-MM-dd"); } public static string ToStringSoutXML(this DateTime? dt) { if (dt == null) return String.Empty; return (dt ?? DateTime.UtcNow).ToString("yyyy-MM-dd"); } public static double GetValueDouble_(this XmlNode input, string name) { double value; if (double.TryParse(input.GetValue(name), NumberStyles.Any, ci.NumberFormat, out value)) return value; return double.MinValue; } public static double GetValueDouble_(this XmlNode input) { double value; if (double.TryParse(input.InnerText, NumberStyles.Any, ci.NumberFormat, out value)) return value; return double.MinValue; } public static void ForEach(this XmlNodeList nodeList, Action action) { foreach (XmlNode node in nodeList) { action(node); } } public static IEnumerable ToList(this XmlNodeList nodeList) { var resultList = new List(); foreach (XmlNode node in nodeList) { resultList.Add(node); } return resultList; } public static IEnumerable Select(this XmlNodeList nodeList, Func action) { var resultList = new List(); foreach (XmlNode node in nodeList) { resultList.Add(action(node)); } return resultList; } /// /// Get the node located along the .
/// If the element could not be found, the element itself and the path to it will be created. ///
/// Root node /// XPath to the node. XPath should only include tag names and separators. /// Target child node public static XmlNode GetOrRestoreByPath(this XmlNode xmlNodeRoot, string path) { XmlNode xmlNodeTarget = xmlNodeRoot.SelectSingleNode(path); if (xmlNodeTarget != null) { return xmlNodeTarget; } string[] pathItems = path.Trim('/').Split('/'); XmlNode xmlNodeCurrent = xmlNodeRoot; foreach (string pathItem in pathItems) { XmlNode xmlNodeItem = xmlNodeCurrent.SelectSingleNode(pathItem); if (xmlNodeItem == null) { xmlNodeItem = xmlNodeCurrent.AppendChild((xmlNodeRoot.OwnerDocument ?? (XmlDocument)xmlNodeRoot).CreateElement(pathItem)); } xmlNodeCurrent = xmlNodeItem; } return xmlNodeCurrent; } public static XmlNode RemoveAllEx(this XmlNode xmlNode) { xmlNode.RemoveAll(); return xmlNode; } public static ItemLog ModifyAttribute(this XmlNode input, ItemLog itemLog, string name, object? value) { itemLog = itemLog ?? new ItemLog(string.Empty, string.Empty, name); itemLog.ValueNew = value?.ToString() ?? string.Empty; XmlAttribute element = input.Attributes[name]; if (element == null) { element = input.OwnerDocument.CreateAttribute(name); input.Attributes.Append(element); } else { itemLog.ValueOld = element.InnerText; } element.InnerText = itemLog.ValueNew; return itemLog.FillType(); } public static ItemLog ModifyElement(this XmlNode input, ItemLog itemLog, string name, object value) { itemLog = itemLog ?? new ItemLog(string.Empty, string.Empty, name); itemLog.ValueNew = value?.ToString() ?? string.Empty; var element = input.SelectSingleNode(name); if (element == null) { element = input.OwnerDocument.CreateElement(name); input.AppendChild(element); } else { itemLog.ValueOld = element.InnerText; } element.InnerText = itemLog.ValueNew; return itemLog.FillType(); } public static ItemLog ModifyElementCData(this XmlNode input, ItemLog itemLog, string name, string value) { itemLog = itemLog ?? new ItemLog(string.Empty, string.Empty, name); itemLog.ValueNew = value?.ToString() ?? string.Empty; var element = input.SelectSingleNode(name); if (element == null) { var root = input.OwnerDocument.CreateElement(name); element = input.OwnerDocument.CreateNode(XmlNodeType.CDATA, name, null); root.AppendChild(element); input.AppendChild(root); } else { itemLog.ValueOld = GetValueCData(element, name); } element.InnerText = itemLog.ValueNew; return itemLog.FillType(); } } }