如何调整XML属性实现重复嵌套Diary标签的反序列化?
处理嵌套重复
<Diary>标签的XML反序列化问题 我在反序列化请求返回的XML结果时,遇到了多层重复的<Diary>标签问题。目前我靠修改XML格式实现了反序列化,但无法修改XML源文件让它只保留单层<Diary>标签。想问下能不能通过调整XML属性来处理反序列化,不用修改响应内容?
XML响应
<?xml version="1.0" ?> <Root> <DiaryDetails> <Diary> <Diary created_user="value1" created_date="value2" long_text="value3" short_text="value4" entry_type="value5" >Value6</Diary> </Diary> <Diary> <Diary created_user="value7" created_date="value8" long_text="value9" short_text="value10" entry_type="value11" >Value12</Diary> </Diary> </DiaryDetails> </Root>
类定义
[XmlRoot("DiaryDetails")] public class Diaries : List<Diary> { } [XmlRoot("Diary")] public class Diary { [XmlAttribute("created_user")] public string CreatedBy { get; set; } [XmlAttribute("created_date")] public string CreatedDate { get; set; } [XmlAttribute("long_text")] public string LongText { get; set; } [XmlAttribute("short_text")] public string ShortText { get; set; } [XmlAttribute("entry_type")] public string Type { get; set; } }
反序列化方法
internal T DeserilaiseObject<T>(string response) { XmlSerializer serializer = new XmlSerializer(typeof(T)); T DeserilaisedObject; using (TextReader reader = new StringReader(response)) { DeserilaisedObject = (T)serializer.Deserialize(reader); } return DeserilaisedObject; }
当前临时解决方法
我目前用字符串替换处理这个问题:
response = response.Replace("<Diary><Diary", "<Diary").Replace("</Diary></Diary>", "</Diary>");
可行解决方案(无需修改XML响应)
可以通过调整XML序列化属性的映射关系,直接适配嵌套的<Diary>标签,以下是两种直观的实现方式:
方案一:层级类映射
新增外层容器类,让序列化器识别嵌套的标签结构:
[XmlRoot("Root")] public class Root { [XmlElement("DiaryDetails")] public DiaryDetails DiaryDetails { get; set; } } public class DiaryDetails { [XmlElement("Diary")] public List<DiaryWrapper> DiaryWrappers { get; set; } } public class DiaryWrapper { [XmlElement("Diary")] public Diary Diary { get; set; } } [XmlRoot("Diary")] public class Diary { [XmlAttribute("created_user")] public string CreatedBy { get; set; } [XmlAttribute("created_date")] public string CreatedDate { get; set; } [XmlAttribute("long_text")] public string LongText { get; set; } [XmlAttribute("short_text")] public string ShortText { get; set; } [XmlAttribute("entry_type")] public string Type { get; set; } [XmlText] public string Content { get; set; } // 新增字段接收<Diary>标签内的文本内容(如Value6) }
反序列化时指定目标类型为Root,再提取实际的Diary列表:
var root = DeserilaiseObject<Root>(response); var diaries = root.DiaryDetails.DiaryWrappers.Select(w => w.Diary).ToList();
方案二:使用XmlAttributeOverrides简化映射
如果不想新增过多类,可以通过XmlAttributeOverrides动态调整序列化规则,不过层级类映射的方式更直观、易维护,适合长期使用。
另外注意:原Diary类缺少接收标签内文本的属性,添加[XmlText]标记的Content字段后,才能完整获取<Diary>标签内的Value6、Value12等内容。
内容的提问来源于stack exchange,提问作者Blag
相关产品推荐
相关产品推荐

