XML
XmlUtility.cs
using EnsatyWorker.Core.Attributes;
using FastDeepCloner;
using EnsatyWorker.Core.Helper;
using EnsatyWorker.Core.InterFace;
using EnsatyWorker.Core.SqlQuerys;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
namespace EnsatyWorker.Core.Object.Library.XML
{
internal static clast XmlUtility
{
///
/// serialize object to xml
///
///
///
public static string ToXml(this object o)
{
string xmlResult = "";
ToXml(o, ref xmlResult);
var xmlDoc = new System.Xml.XmlDocameent();
StringWriter sw = new StringWriter();
xmlDoc.LoadXml(xmlResult);
xmlDoc.Save(sw);
return sw.ToString();
}
///
/// DeSerilize Xml to object, this is supposed to handle all unknow object types but there has not been to many tests.
///
///
///
///
public static object FromXml(this string xml, IRepository transaction = null)
{
if (string.IsNullOrEmpty(xml))
return null;
var doc = new System.Xml.XmlDocameent();
doc.LoadXml(xml);
var o = FromXml(doc.DocameentElement);
void LoadXmlIgnoreProperties(object item)
{
if (item is IList)
{
foreach (var t in (IList)item)
LoadXmlIgnoreProperties(t);
return;
}
var type = item?.GetType().GetActualType();
if (type == null)
return;
if (!(item?.GetPrimaryKeyValue().ObjectIsNew() ?? true))
{
var primaryId = item.GetPrimaryKeyValue();
foreach (var prop in DeepCloner.GetFastDeepClonerProperties(item.GetType()).Where(x => (x.ContainAttribute() || !x.IsInternalType) && !x.ContainAttribute() && x.CanRead))
{
var value = prop.GetValue(item);
if (prop.PropertyType == typeof(string) && string.IsNullOrEmpty(value?.ToString()))
value = string.Empty;
if (prop.IsInternalType && value == LightDataTableShared.ValueByType(prop.PropertyType)) // Value is default
{
var cmd = transaction.GetSqlCommand($"SELECT [{prop.GetPropertyName()}] FROM {type.TableName().GetName(transaction.DataBaseTypes)} WHERE [{item.GetPrimaryKey().GetPropertyName()}] = {Querys.GetValueByType(item.GetPrimaryKeyValue(), transaction.DataBaseTypes)}");
var data = transaction.ExecuteScalar(cmd);
if (data == null)
continue;
if (prop.ContainAttribute())
data = new DataCipher(prop.GetCustomAttribute().Key, prop.GetCustomAttribute().KeySize).Decrypt(data.ToString());
else if (prop.ContainAttribute() && data.ToString().IsBase64String())
data = MethodHelper.DecodeStringFromBase64(data.ToString());
prop.SetValue(item, data.ConvertValue(prop.PropertyType));
}
else if (value != null) LoadXmlIgnoreProperties(value);
}
}
}
if (transaction != null)
LoadXmlIgnoreProperties(o);
return o;
}
///
/// DeSerilize Xml to object, this is supposed to handle all unknow object types but there has not been to many tests.
///
///
///
///
public static T FromXml(this string xml, IRepository transaction) where T : clast
{
if (string.IsNullOrEmpty(xml))
return (T)(new object());
var doc = new System.Xml.XmlDocameent();
doc.LoadXml(xml);
var o = (T)FromXml(doc.DocameentElement);
void LoadXmlIgnoreProperties(object item)
{
if (item is IList)
{
foreach (var t in (IList)item)
LoadXmlIgnoreProperties(t);
return;
}
var type = item?.GetType().GetActualType();
if (type == null)
return;
if (!(item?.GetPrimaryKeyValue().ObjectIsNew() ?? true))
{
var primaryId = item.GetPrimaryKeyValue();
foreach (var prop in DeepCloner.GetFastDeepClonerProperties(item.GetType()).Where(x => (x.ContainAttribute() || !x.IsInternalType) && !x.ContainAttribute() && x.CanRead))
{
var value = prop.GetValue(item);
if (prop.PropertyType == typeof(string) && string.IsNullOrEmpty(value?.ToString()))
value = string.Empty;
if (prop.IsInternalType && value == LightDataTableShared.ValueByType(prop.PropertyType)) // Value is default
{
var cmd = transaction.GetSqlCommand($"SELECT [{prop.GetPropertyName()}] FROM {type.TableName().GetName(transaction.DataBaseTypes)} WHERE [{item.GetPrimaryKey().GetPropertyName()}] = {Querys.GetValueByType(item.GetPrimaryKeyValue(), transaction.DataBaseTypes)}");
var data = transaction.ExecuteScalar(cmd);
if (data == null)
continue;
if (prop.ContainAttribute())
data = new DataCipher(prop.GetCustomAttribute().Key, prop.GetCustomAttribute().KeySize).Decrypt(data.ToString());
else if (prop.ContainAttribute() && data.ToString().IsBase64String())
data = MethodHelper.DecodeStringFromBase64(data.ToString());
prop.SetValue(item, data.ConvertValue(prop.PropertyType));
}
else if (value != null) LoadXmlIgnoreProperties(value);
}
}
}
if (transaction != null)
LoadXmlIgnoreProperties(o);
return o;
}
private static object FromXml(XmlNode doc)
{
var fullType = Type.GetType(doc.Attributes["FullName"].Value);
object item = fullType.CreateInstance();
var subtype = fullType.GetActualType();
foreach (XmlNode chil in doc.ChildNodes)
{
var prop = DeepCloner.GetProperty(subtype, chil.Name);
if (chil.Attributes["FullName"] != null && prop == null)
{
if (chil.Name != "List")
((IList)item).Add(FromXml(chil));
else foreach (var t in FromXml(chil) as IList)
((IList)item).Add(t);
continue;
}
if (prop != null && prop.IsInternalType)
prop.SetValue(item, chil.InnerText.ConvertValue(prop.PropertyType));
else if (chil.Attributes["FullName"] != null)
prop.SetValue(item, FromXml(chil));
else ((IList)item).Add(chil.InnerText.ConvertValue(item.GetType().GetActualType()));
}
return item;
}
private static string ToXml(object o, ref string xml, bool addStart = true, string propName = "")
{
if (addStart)
xml += "";
var name = string.IsNullOrWhiteSpace(propName) ? new Regex("[^a-zA-Z]").Replace(o.GetType().Name, "") : propName;
var quName = o.GetType().astemblyQualifiedName;
if (o.GetType().IsInternalType())
{
if (o is byte[])
o = Convert.ToBase64String(o as byte[]);
xml += $"{o}";
return xml;
}
xml += $"";
if (o is IList)
{
foreach (var item in (IList)o)
ToXml(item, ref xml, false);
}
else
{
foreach (var prop in DeepCloner.GetFastDeepClonerProperties(o.GetType()).Where(x => !x.ContainAttribute()))
{
var value = prop.GetValue(o);
if (value == null)
continue;
var zName = prop.Name;
if (value is byte[])
value = Convert.ToBase64String(value as byte[]);
if (value.GetType().IsInternalType())
xml += $"{value}";
else ToXml(value, ref xml, false, zName);
}
}
xml += $"";
return xml;
}
}
}