util/csharp/core/Utils/XmlUtil.cs (249 lines of code) (raw):

using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Xml; using System.Xml.Linq; using Tea; namespace AlibabaCloud.OSSUtil.Utils { internal class XmlUtil { internal static Dictionary<string, object> DeserializeXml(string xmlStr, Type type) { Dictionary<string, object> result = new Dictionary<string, object>(); XmlDocument contentXmlDoc = new XmlDocument(); contentXmlDoc.LoadXml(xmlStr); XmlNodeList nodeList = contentXmlDoc.ChildNodes; for (int i = 0; i < nodeList.Count; i++) { XmlNode root = nodeList.Item(i); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo p in properties) { Type propertyType = p.PropertyType; NameInMapAttribute attribute = p.GetCustomAttribute(typeof(NameInMapAttribute)) as NameInMapAttribute; string realName = attribute == null ? p.Name : attribute.Name; if (root.Name == realName) { if (!typeof(TeaModel).IsAssignableFrom(propertyType)) { result.Add(realName, root.InnerText); } else { result.Add(realName, getDictFromXml(root, propertyType)); } } } } return result; } private static Dictionary<string, object> getDictFromXml(XmlNode element, Type type) { Dictionary<string, object> nodeDict = new Dictionary<string, object>(); PropertyInfo[] properties = type.GetProperties(); for (int i = 0; i < properties.Length; i++) { PropertyInfo p = properties[i]; Type propertyType = p.PropertyType; NameInMapAttribute attribute = p.GetCustomAttribute(typeof(NameInMapAttribute)) as NameInMapAttribute; string realName = attribute == null ? p.Name : attribute.Name; XmlNodeList node = element.SelectNodes(realName); if (node != null && node.Count > 0 && StringUtils.SubStringCount(node[0].OuterXml, realName) > 1) { if (typeof(IList).IsAssignableFrom(propertyType)) { Type innerPropertyType = propertyType.GetGenericArguments()[0]; if (typeof(TeaModel).IsAssignableFrom(innerPropertyType)) { IList dicList = new List<Dictionary<string, object>>(); for (int j = 0; j < node.Count; j++) { dicList.Add(getDictFromXml(node.Item(j), innerPropertyType)); } nodeDict.Add(realName, dicList); } else { var dicList = (IList)Activator.CreateInstance(propertyType); for (int j = 0; j < node.Count; j++) { var value = mapObj(innerPropertyType, node.Item(j).InnerText); dicList.Add(value); } nodeDict.Add(realName, dicList); } } else if (typeof(TeaModel).IsAssignableFrom(propertyType)) { nodeDict.Add(realName, getDictFromXml(node.Item(0), propertyType)); } else { string value = node.Item(0).InnerText; nodeDict.Add(realName, mapObj(propertyType, value)); } } else { nodeDict.Add(realName, null); } } return nodeDict; } private static object mapObj(Type propertyType, string value) { if (value == null) { return null; } else if (propertyType == typeof(int?)) { return Convert.ToInt32(value); } else if (propertyType == typeof(long?)) { return Convert.ToInt64(value); } else if (propertyType == typeof(float?)) { return Convert.ToSingle(value); } else if (propertyType == typeof(double?)) { return Convert.ToDouble(value); } else if (propertyType == typeof(bool?)) { return Convert.ToBoolean(value); } else if (propertyType == typeof(short?)) { return Convert.ToInt16(value); } else if (propertyType == typeof(ushort?)) { return Convert.ToUInt16(value); } else if (propertyType == typeof(uint?)) { return Convert.ToUInt32(value); } else if (propertyType == typeof(ulong?)) { return Convert.ToUInt64(value); } else { return Convert.ChangeType(value, propertyType); } } internal static string SerializeXml(object obj) { Type type = obj.GetType(); if (typeof(TeaModel).IsAssignableFrom(type)) { return SerializeXmlByModel((TeaModel)obj); } else if (obj is Dictionary<string, object>) { return SerializeXmlByDict((Dictionary<string, object>)obj); } else { return string.Empty; } } internal static string SerializeXmlByModel(TeaModel obj) { Type type = obj.GetType(); PropertyInfo[] properties = type.GetProperties(); if (obj == null || properties.Length == 0) { return string.Empty; } PropertyInfo propertyInfo = properties[0]; NameInMapAttribute attribute = propertyInfo.GetCustomAttribute(typeof(NameInMapAttribute)) as NameInMapAttribute; string realName = attribute == null ? propertyInfo.Name : attribute.Name; object rootObj = propertyInfo.GetValue(obj); XElement element = new XElement(realName); GetXmlFactory(rootObj, element); return element.ToString(); } private static string SerializeXmlByDict(Dictionary<string, object> dict) { if (dict == null || dict.Count == 0) { return string.Empty; } string nodeName = dict.Keys.ToList()[0]; XElement element = new XElement(nodeName); GetXmlFactory(dict[nodeName], element); return element.ToString(); } private static void GetXmlFactory(object obj, XElement element, XElement xParent = null) { if (obj == null) { return; } Type type = obj.GetType(); if (typeof(IList).IsAssignableFrom(type)) { if (xParent == null) { throw new ArgumentException("unsupported nest list."); } IList list = (IList)obj; string nodeName = element.Name.LocalName; for (int j = 0; j < list.Count; j++) { XElement xNode = new XElement(nodeName); GetXmlFactory(list[j], xNode); xParent.Add(xNode); } return; } if (typeof(TeaModel).IsAssignableFrom(type)) { GetXml((TeaModel)obj, element); } else if (obj is Dictionary<string, object>) { GetXml((Dictionary<string, object>)obj, element); } else { element.Add(obj); } if (xParent != null) { xParent.Add(element); } } private static void GetXml(Dictionary<string, object> dict, XElement element) { foreach (var keypair in dict) { XElement xNode = new XElement(keypair.Key); GetXmlFactory(keypair.Value, xNode, element); } } private static void GetXml(TeaModel model, XElement element) { Type type = model.GetType(); PropertyInfo[] properties = type.GetProperties(); for (int i = 0; i < properties.Length; i++) { PropertyInfo propertyInfo = properties[i]; Type property = propertyInfo.PropertyType; NameInMapAttribute attribute = propertyInfo.GetCustomAttribute(typeof(NameInMapAttribute)) as NameInMapAttribute; string realName = attribute == null ? propertyInfo.Name : attribute.Name; XElement node = new XElement(realName); GetXmlFactory(propertyInfo.GetValue(model), node, element); } } } }