如何让VB.NET类兼容两个XML根元素?多次XmlRoot属性报错
实现VB.NET Xml序列化兼容多个根元素名
当然可行!不过直接给类加两个XmlRoot属性确实行不通,因为XmlRootAttribute本身没有标记AllowMultiple=True,所以VB.NET不允许重复应用这个属性。不过有几种简单的办法可以实现你要的向后兼容,我给你详细说下:
方法1:自定义XmlReader替换根元素名
这种思路是在读取XML的时候,把旧的根元素名替换成新的,让序列化器以为它一直处理的是cancellation-response。你只需要继承XmlTextReader,重写相关属性即可:
Public Class RootReplacingReader Inherits XmlTextReader Public Sub New(reader As TextReader) MyBase.New(reader) End Sub ' 重写LocalName,遇到旧根元素时返回新名称 Public Overrides ReadOnly Property LocalName As String Get If MyBase.LocalName = "applicant-response" Then Return "cancellation-response" End If Return MyBase.LocalName End Get End Property End Class
使用的时候,用这个自定义的Reader来反序列化:
Dim xmlContent As String = "你的XML内容" Dim serializer As New XmlSerializer(GetType(ApplicantResponse)) Using reader As New RootReplacingReader(New StringReader(xmlContent)) Dim response = DirectCast(serializer.Deserialize(reader), ApplicantResponse) ' 这里处理反序列化后的对象 End Using
这种方法的好处是调用方几乎不需要修改原有代码,只需要替换Reader即可,非常透明。
方法2:使用XmlAttributeOverrides创建多序列化器
另一种思路是创建两个序列化器:一个对应新的根元素名,一个对应旧的。然后尝试用两个序列化器分别反序列化,直到成功:
' 创建针对旧根元素的属性重写配置 Dim overrides As New XmlAttributeOverrides() Dim oldRootAttr As New XmlRootAttribute("applicant-response") overrides.Add(GetType(ApplicantResponse), oldRootAttr) ' 初始化两个序列化器 Dim defaultSerializer As New XmlSerializer(GetType(ApplicantResponse)) Dim oldRootSerializer As New XmlSerializer(GetType(ApplicantResponse), overrides) Dim response As ApplicantResponse = Nothing Dim xmlContent As String = "你的XML内容" Using reader As New StringReader(xmlContent) Try ' 先尝试用默认的根元素反序列化 response = DirectCast(defaultSerializer.Deserialize(reader), ApplicantResponse) Catch ex As InvalidOperationException ' 如果失败,重置Reader位置,尝试旧根元素的序列化器 reader.BaseStream.Position = 0 response = DirectCast(oldRootSerializer.Deserialize(reader), ApplicantResponse) End Try End Using
这种方法更灵活,如果以后需要支持更多根元素名,只需要添加对应的序列化器即可。不过要注意捕获反序列化的异常,并且重置Reader的位置。
总结
这两种方法都能完美解决你的需求,你可以根据自己的场景选择:如果希望代码改动最小,选方法1;如果需要支持多种根元素或者更灵活的配置,选方法2。
内容的提问来源于stack exchange,提问作者Mayron
相关产品推荐
相关产品推荐

