C#Xml序列化,集合和根元素
我的应用程序串行化流中的对象.
以下是我需要的样本: <links> <link href="/users" rel="users" /> <link href="/features" rel="features" /> </links> 在这种情况下,对象是’links’对象的集合. ———–第一版 起初我使用DataContractSerializer,但是不能将成员序列化为属性(source) 这是对象: [DataContract(Name="link")] public class LinkV1 { [DataMember(Name="href")] public string Url { get; set; } [DataMember(Name="rel")] public string Relationship { get; set; } } 结果如下: <ArrayOflink xmlns:i="...." xmlns="..."> <link> <href>/users</href> <rel>users</rel> </link> <link> <href>/features</href> <rel>features</rel> </link> </ArrayOflink> ———–第二版 好的,不安静我想要的,所以我尝试了经典的XmlSerializer,但是…哦,哦,你不能指定根元素的名称&的集合元素如果根元素是一个集合… 这是代码: [XmlRoot("link")] public class LinkV2 { [XmlAttribute("href")] public string Url { get; set; } [XmlAttribute("rel")] public string Relationship { get; set; } } 结果如下: <ArrayOfLinkV2> <LinkV2 href="/users" rel="users" /> <LinkV2 href="/features" rel="features" /> <LinkV2 href="/features/user/{keyUser}" rel="featuresByUser" /> </ArrayOfLinkV2> ———–第三版 使用XmlSerializer一个根元素: [XmlRoot("trick")] public class TotallyUselessClass { [XmlArray("links"),XmlArrayItem("link")] public List<LinkV2> Links { get; set; } } 其结果: <trick> <links> <link href="/users" rel="users" /> <link href="/features" rel="features" /> <link href="/features/user/{keyUser}" rel="featuresByUser" /> </links> </trick> 尼斯,但我不想要那个根节点! 以下是约束: >序列化代码是通用的,它可以与任何可序列化的方式一起使用 我现在的解决方案是什么 编码我自己的XmlSerializer 任何想法 ? 在这个问题上真正困扰我的是,我想要的似乎真的很简单 解决方法
好的,这是我的最终解决方案(希望它有助于某人),可以序列化一个纯数组,List<>,HashSet&
要实现这一点,我们需要告诉serializer什么根节点使用,这是一个棘手的… 1)在可序列化的对象上使用’XmlType’ [XmlType("link")] public class LinkFinalVersion { [XmlAttribute("href")] public string Url { get; set; } [XmlAttribute("rel")] public string Relationship { get; set; } } 2)编写一个“智能根检测器收集”方法,这将返回一个XmlRootAttribute private XmlRootAttribute XmlRootForCollection(Type type) { XmlRootAttribute result = null; Type typeInner = null; if(type.IsGenericType) { var typeGeneric = type.GetGenericArguments()[0]; var typeCollection = typeof (ICollection<>).MakeGenericType(typeGeneric); if(typeCollection.IsAssignableFrom(type)) typeInner = typeGeneric; } else if(typeof (ICollection).IsAssignableFrom(type) && type.HasElementType) { typeInner = type.GetElementType(); } // yeepeeh ! if we are working with a collection if(typeInner != null) { var attributes = typeInner.GetCustomAttributes(typeof (XmlTypeAttribute),true); if((attributes != null) && (attributes.Length > 0)) { var typeName = (attributes[0] as XmlTypeAttribute).TypeName + 's'; result = new XmlRootAttribute(typeName); } } return result; } 3)将该XmlRootAttribute推送到序列化程序中 // hack : get the XmlRootAttribute if the item is a collection var root = XmlRootForCollection(type); // create the serializer var serializer = new XmlSerializer(type,root); 我告诉你这很棘手;) 为了改善这一点,您可以: A)创建一个XmlTypeInCollectionAttribute来指定自定义根名称(如果基本的复合不符合您的需要) [XmlType("link")] [XmlTypeInCollection("links")] public class LinkFinalVersion { } B)如果可能,缓存您的XmlSerializer(例如在静态字典中). 在我的测试中,建立一个没有XmlRootAttributes的XmlSerializer需要3ms.如果指定一个XmlRootAttribute,它大约需要80ms(只需要一个自定义的根节点名称!) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |