You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET XmlSerializer实现带属性元素与序号化元素序列化

嘿,刚好我之前处理过类似的XML序列化需求,给你一步步解决这两个问题:

需求1:实现带属性的Block元素(同时包含文本和id_Block属性)

原来的Block是简单的字符串类型,没法同时包含属性和文本值,我们需要把它改成一个自定义类,用XmlAttribute标记属性,XmlText标记文本内容:

Public Class Block
    <XmlAttribute("id_Block")>
    Public Property IdBlock As Integer

    <XmlText>
    Public Property Text As String
End Class

然后修改Xyz类里的Block属性类型:

Public Class Xyz
    ' 保留其他原有属性...
    <XmlElement("Block")>
    Public Property Block As Block

    Public Sub New()
        test = New List(Of Test)
    End Sub
End Class

赋值的时候直接实例化Block类即可:

xyz.Block = New Block() With {.IdBlock = 5, .Text = "Abc"}

这样序列化后就能得到<Block id_Block=5>Abc</Block>的结构。

需求2:生成带序号后缀的Test_0、Test_1元素

默认的XmlSerializer处理列表时只会生成同名元素,没法动态添加序号后缀,这时候需要让Xyz类实现IXmlSerializable接口,手动控制序列化过程:

修改后的完整Xyz类(包含两个需求的实现):

Imports System.Xml
Imports System.Xml.Serialization

Public Class Xyz
    <XmlAttribute>
    Public Property id As Integer

    <XmlElement>
    Public Property name As String

    <XmlElement>
    Public Property comment As String

    <XmlElement("Block")>
    Public Property Block As Block

    ' 保留Test列表用于存储数据
    Public Property test As List(Of Test)

    Public Sub New()
        test = New List(Of Test)
    End Sub

    ' 实现IXmlSerializable接口
    Public Function GetSchema() As XmlSchema Implements IXmlSerializable.GetSchema
        Return Nothing
    End Function

    Public Sub ReadXml(reader As XmlReader) Implements IXmlSerializable.ReadXml
        ' 反序列化逻辑(如果需要导入XML的话)
        id = Integer.Parse(reader.GetAttribute("id"))
        reader.ReadStartElement()

        While reader.NodeType <> XmlNodeType.EndElement
            Select Case reader.LocalName
                Case "name"
                    name = reader.ReadElementContentAsString()
                Case "comment"
                    comment = reader.ReadElementContentAsString()
                Case "Block"
                    Dim block = New Block()
                    block.IdBlock = Integer.Parse(reader.GetAttribute("id_Block"))
                    block.Text = reader.ReadElementContentAsString()
                    Me.Block = block
                Case Else
                    ' 解析带序号的Test_*元素
                    If reader.LocalName.StartsWith("Test_") Then
                        Dim testObj = New Test()
                        reader.ReadStartElement()
                        testObj.name = reader.ReadElementContentAsString()
                        reader.ReadEndElement()
                        test.Add(testObj)
                    Else
                        reader.Skip()
                    End If
            End Select
        End While
        reader.ReadEndElement()
    End Sub

    Public Sub WriteXml(writer As XmlWriter) Implements IXmlSerializable.WriteXml
        ' 手动序列化id属性
        writer.WriteAttributeString("id", id.ToString())

        ' 序列化name、comment元素
        If Not String.IsNullOrEmpty(name) Then
            writer.WriteElementString("name", name)
        End If
        If Not String.IsNullOrEmpty(comment) Then
            writer.WriteElementString("comment", comment)
        End If

        ' 序列化Block元素
        If Block IsNot Nothing Then
            writer.WriteStartElement("Block")
            writer.WriteAttributeString("id_Block", Block.IdBlock.ToString())
            writer.WriteString(Block.Text)
            writer.WriteEndElement()
        End If

        ' 生成带序号的Test元素
        For i = 0 To test.Count - 1
            writer.WriteStartElement($"Test_{i}")
            ' 序列化单个Test对象
            Dim testSerializer = New XmlSerializer(GetType(Test))
            testSerializer.Serialize(writer, test(i))
            writer.WriteEndElement()
        Next
    End Sub
End Class

Public Class Test
    <XmlElement>
    Public Property name As String
End Class

Public Class Block
    <XmlAttribute("id_Block")>
    Public Property IdBlock As Integer

    <XmlText>
    Public Property Text As String
End Class

关键说明:

  • 在WriteXml方法里,我们遍历test列表,动态创建Test_0、Test_1这样的元素名,然后用子序列化器把每个Test对象写入对应元素。
  • 如果需要支持反序列化(也就是导入XML到对象),ReadXml方法里的逻辑已经帮你处理了解析带序号的Test元素,直接用即可。

测试序列化代码:

Dim xyz = New Xyz() With {
    .id = 0,
    .name = "Abc",
    .comment = "Abc",
    .Block = New Block() With {.IdBlock = 5, .Text = "Abc"}
}
xyz.test.Add(New Test() With {.name = "Abc"})
xyz.test.Add(New Test() With {.name = "Def"})
xyz.test.Add(New Test() With {.name = "Ghi"})

Dim serializer = New XmlSerializer(GetType(Xyz))
Using writer = New StreamWriter("output.xml")
    serializer.Serialize(writer, xyz)
End Using

运行后生成的XML完全符合你要的目标结构。

内容的提问来源于stack exchange,提问作者Cit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:07:49