c# – 如何为XmlElement字段定义多个名称?
发布时间:2020-12-15 06:53:12 所属栏目:百科 来源:网络整理
导读:我有一个客户端应用程序提供的 XML文档到我的C#应用??程序.这是客户端如何发送XML文件: ?xml version="1.0" encoding="utf-8"?SomeAccount parentId2380983/parentId !-- more elements --/SomeAccount 还有一个支持XML反序列化的C#类: [XmlRoot]public cl
我有一个客户端应用程序提供的
XML文档到我的C#应用??程序.这是客户端如何发送XML文件:
<?xml version="1.0" encoding="utf-8"?> <SomeAccount> <parentId>2380983</parentId> <!-- more elements --> </SomeAccount> 还有一个支持XML反序列化的C#类: [XmlRoot] public class SomeAccount { [XmlElement("parentId")] public long ParentId { get; set; } //rest of fields... } 但是有些客户端系统以这种方式发送XML(请注意LeParentId中的大写字母): <?xml version="1.0" encoding="utf-8"?> <SomeAccount> <LeParentId>2380983</LeParentId> <!-- similar for the other elements --> </SomeAccount> 我如何使此字段(和其他人)同时支持XML名称parentId和LeParentId? 这是我目前用于XML反序列化的方法: public sealed class XmlSerializationUtil { public static T Deserialize<T>(string xml) { if (xml == null) return default(T); XmlSerializer serializer = new XmlSerializer(typeof(T)); StringReader stringReader = new StringReader(xml); return (T)serializer.Deserialize(stringReader); } } 我尝试在字段中添加两次[XmlElement],每个元素名称有一个,但是没有起作用. 解决方法
采取2 – 让我们使用未知的元素处理事件来实现这一点(请参见下面的注释,但是有一些限制):
public class XmlSynonymDeserializer : XmlSerializer { public class SynonymsAttribute : Attribute { public readonly ISet<string> Names; public SynonymsAttribute(params string[] names) { this.Names = new HashSet<string>(names); } public static MemberInfo GetMember(object obj,string name) { Type type = obj.GetType(); var result = type.GetProperty(name); if (result != null) return result; foreach (MemberInfo member in type.GetProperties().Cast<MemberInfo>().Union(type.GetFields())) foreach (var attr in member.GetCustomAttributes(typeof(SynonymsAttribute),true)) if (attr is SynonymsAttribute && ((SynonymsAttribute)attr).Names.Contains(name)) return member; return null; } } public XmlSynonymDeserializer(Type type) : base(type) { this.UnknownElement += this.SynonymHandler; } public XmlSynonymDeserializer(Type type,XmlRootAttribute root) : base(type,root) { this.UnknownElement += this.SynonymHandler; } protected void SynonymHandler(object sender,XmlElementEventArgs e) { var member = SynonymsAttribute.GetMember(e.ObjectBeingDeserialized,e.Element.Name); Type memberType; if (member != null && member is FieldInfo) memberType = ((FieldInfo)member).FieldType; else if (member != null && member is PropertyInfo) memberType = ((PropertyInfo)member).PropertyType; else return; if (member != null) { object value; XmlSynonymDeserializer serializer = new XmlSynonymDeserializer(memberType,new XmlRootAttribute(e.Element.Name)); using (System.IO.StringReader reader = new System.IO.StringReader(e.Element.OuterXml)) value = serializer.Deserialize(reader); if (member is FieldInfo) ((FieldInfo)member).SetValue(e.ObjectBeingDeserialized,value); else if (member is PropertyInfo) ((PropertyInfo)member).SetValue(e.ObjectBeingDeserialized,value); } } } 现在类的实际代码是: [XmlRoot] public class SomeAccount { [XmlElement("parentId")] [XmlSynonymDeserializer.Synonyms("LeParentId","AnotherGreatName")] public long ParentId { get; set; } //rest of fields... } 要反序列化,只需使用XmlSynonymDeserializer而不是常规的XmlSerializer.这应该适用于大多数基本需求. 已知限制: >此实现仅支持具有多个名称的元素;扩展它的属性应该是微不足道的>在实体继承彼此的情况下,对属性/字段的处理的支持未被测试>此实现不检查编程错误(具有只读/常量字段/属性的属性,具有相同同义词的多个成员等) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |