序列化并编写许多相同的XML元素

时间:2017-10-23 03:12:56

标签: xml vb.net serialization

我将3,146个行星反序列化为对象,为它们可能具有的任何空标记生成新值,然后将它们全部序列化到创建新xml文档的编写器。一些行星有多个landMass,satellite和factionChange标签。我的代码(谢谢@djv)正确地写出了factionChange标签,它们都有数据和派系子节点。但是landMass和Satellite继续只打印New XML screenshot

我尝试过:(来自Question 24246002

<System.Xml.Serialization.XmlArrayItem("satellite", GetType(String))>
Public Property satellite() As List(Of String)

<System.Xml.Serialization.XmlArrayItem("landMass", GetType(String))>
Public Property landMass() As List(Of String)

<System.Xml.Serialization.XmlElementAttribute("hpg", GetType(String))>
Public Property HPGStation() As String

<System.Xml.Serialization.XmlElementAttribute("faction", GetType(String))>
Public Property faction() As String

<System.Xml.Serialization.XmlElementAttribute("factionChange", GetType(planetsPlanetFactionChange))>
Public Property factionChange() As planetsPlanetFactionChange()

<System.Xml.Serialization.XmlElementAttribute("desc", GetType(String))>
Public Property desc() As String()

Private Sub New()

    satellite = New List(Of String)()
    landMass = New List(Of String)()

End Sub

我最初的代码是这样的:

    <System.Xml.Serialization.XmlElementAttribute("satellite", GetType(String))>
    Public Property satellite() As planetsPlanetSatellite()

    <System.Xml.Serialization.XmlElementAttribute("landMass", GetType(String))>
    Public Property landMass() As planetsPlanetLandMass()

    <System.Xml.Serialization.XmlElementAttribute("hpg", GetType(String))>
    Public Property HPGStation() As String

    <System.Xml.Serialization.XmlElementAttribute("faction", GetType(String))>
    Public Property faction() As String

    <System.Xml.Serialization.XmlElementAttribute("factionChange", GetType(planetsPlanetFactionChange))>
    Public Property factionChange() As planetsPlanetFactionChange()

    <System.Xml.Serialization.XmlElementAttribute("desc", GetType(String))>
    Public Property desc() As String()

End Class

'''<remarks/>
<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanetFactionChange

    Private dateField As Date

    Private factionField As String

    <System.Xml.Serialization.XmlElementAttribute(DataType:="date")>
    Public Property [date]() As Date

    <System.Xml.Serialization.XmlElementAttribute("faction", GetType(String))>
    Public Property faction() As String

End Class

<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanetSatellite

    Private satelliteField As String

    <System.Xml.Serialization.XmlElementAttribute("satellite", GetType(String))>
    Public Property satellite() As String

End Class

<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanetLandMass

    Private landMassField As String

    <System.Xml.Serialization.XmlElementAttribute("landMass", GetType(String))>
    Public Property landMass() As String

End Class

我刚刚复制了factionChange是如何完成的,因为它起作用但是对于landMass和卫星不起作用。

所以,问题是如何序列化并让XmlWriter写出多个landMass和卫星标签(如果行星有它们)到新的xml文件。

Planets.vb

Imports System.Xml.Serialization
'''<remarks/>
<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True),
 System.Xml.Serialization.XmlRootAttribute("planets", IsNullable:=False)>
Partial Public Class Planets

    Private planetField() As planetsPlanet

    '''<remarks/>
    <System.Xml.Serialization.XmlElementAttribute("planet")>
    Public Property planet() As planetsPlanet()

End Class

'''<remarks/>
<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanet

    <System.Xml.Serialization.XmlElementAttribute("name", GetType(String))>
    Public Property name() As String

    <System.Xml.Serialization.XmlElementAttribute("xcood", GetType(Decimal?))>
    Public Property xcood() As Decimal?

    <System.Xml.Serialization.XmlElementAttribute("ycood", GetType(Decimal?))>
    Public Property ycood() As Decimal?

    <System.Xml.Serialization.XmlElementAttribute("station", GetType(String))>
    Public Property station() As String

    <System.Xml.Serialization.XmlElementAttribute("spectralClass", GetType(String))>
    Public Property spectralClass() As String

    <System.Xml.Serialization.XmlElementAttribute("subtype", GetType(Integer?))>
    Public Property subtype() As Integer?

    <System.Xml.Serialization.XmlElementAttribute("luminosity", GetType(String))>
    Public Property luminosity() As String

    <System.Xml.Serialization.XmlElementAttribute("spectralType", GetType(String))>
    Public Property spectralType() As String

    <XmlIgnoreAttribute()>
    Public mass As Decimal
    <XmlIgnoreAttribute()>
    Public innerLife As Decimal
    <XmlIgnoreAttribute()>
    Public outerLife As Decimal
    <XmlIgnoreAttribute()>
    Public slot1 As Decimal
    <XmlIgnoreAttribute()>
    Public slot2 As Decimal
    <XmlIgnoreAttribute()>
    Public slot3 As Decimal
    <XmlIgnoreAttribute()>
    Public slot4 As Decimal
    <XmlIgnoreAttribute()>
    Public slot5 As Decimal
    <XmlIgnoreAttribute()>
    Public slot6 As Decimal
    <XmlIgnoreAttribute()>
    Public slot7 As Decimal
    <XmlIgnoreAttribute()>
    Public slot8 As Decimal
    <XmlIgnoreAttribute()>
    Public slot9 As Decimal
    <XmlIgnoreAttribute()>
    Public slot10 As Decimal
    <XmlIgnoreAttribute()>
    Public slot11 As Decimal
    <XmlIgnoreAttribute()>
    Public slot12 As Decimal
    <XmlIgnoreAttribute()>
    Public slot13 As Decimal
    <XmlIgnoreAttribute()>
    Public slot14 As Decimal
    <XmlIgnoreAttribute()>
    Public slot15 As Decimal

    <System.Xml.Serialization.XmlElementAttribute("nadirCharge", GetType(String))>
    Public Property nadirCharge() As String

    <System.Xml.Serialization.XmlElementAttribute("zenithCharge", GetType(String))>
    Public Property zenithCharge() As String

    <System.Xml.Serialization.XmlElementAttribute("sysPos", GetType(Integer?))>
    Public Property sysPos() As Integer?

    <System.Xml.Serialization.XmlElementAttribute("axis", GetType(String))>
    Public Property axis() As String

    <System.Xml.Serialization.XmlElementAttribute("orbit", GetType(String))>
    Public Property orbit() As String

    <System.Xml.Serialization.XmlElementAttribute("pressure", GetType(Integer?))>
    Public Property pressure() As Integer?

    <System.Xml.Serialization.XmlElementAttribute("gravity", GetType(Decimal?))>
    Public Property gravity() As Decimal?

    <System.Xml.Serialization.XmlElementAttribute("lifeForm", GetType(Integer?))>
    Public Property lifeForm() As Integer?

    <System.Xml.Serialization.XmlElementAttribute("climate", GetType(Integer?))>
    Public Property climate() As Integer?

    <System.Xml.Serialization.XmlElementAttribute("percentWater", GetType(Integer?))>
    Public Property percentWater() As Integer?

    <System.Xml.Serialization.XmlElementAttribute("temperature", GetType(Integer?))>
    Public Property temperature() As Integer?

    <System.Xml.Serialization.XmlElementAttribute("socioIndustrial", GetType(String))>
    Public Property socioIndustrial() As String()

    <System.Xml.Serialization.XmlElementAttribute("satellite", GetType(String))>
    Public Property satellite() As planetsPlanetSatellite()

    <System.Xml.Serialization.XmlElementAttribute("landMass", GetType(String))>
    Public Property landMass() As planetsPlanetLandMass()

    <System.Xml.Serialization.XmlElementAttribute("hpg", GetType(String))>
    Public Property HPGStation() As String

    <System.Xml.Serialization.XmlElementAttribute("faction", GetType(String))>
    Public Property faction() As String

    <System.Xml.Serialization.XmlElementAttribute("factionChange", GetType(planetsPlanetFactionChange))>
    Public Property factionChange() As planetsPlanetFactionChange()

    <System.Xml.Serialization.XmlElementAttribute("desc", GetType(String))>
    Public Property desc() As String()

End Class

'''<remarks/>
<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanetFactionChange

    Private dateField As Date

    Private factionField As String

    <System.Xml.Serialization.XmlElementAttribute(DataType:="date")>
    Public Property [date]() As Date

    <System.Xml.Serialization.XmlElementAttribute("faction", GetType(String))>
    Public Property faction() As String

End Class

<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanetSatellite

    Private satelliteField As String

    <System.Xml.Serialization.XmlElementAttribute("satellite", GetType(String))>
    Public Property satellite() As String

End Class

<System.SerializableAttribute(),
 System.ComponentModel.DesignerCategoryAttribute("code"),
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanetLandMass

    Private landMassField As String

    <System.Xml.Serialization.XmlElementAttribute("landMass", GetType(String))>
    Public Property landMass() As String

End Class

objPlanets.vb

Imports System.Xml
Imports System.Xml.Serialization

Class objPlanets

    Private Shared ReadOnly r As New Random()

    Private Sub serialPlanets()

        Dim serial As New XmlSerializer(GetType(Planets))
        Dim p As New Planets
        Dim reader As XmlReader = XmlReader.Create(My.Application.Info.DirectoryPath & "\Planets\planetsTemplate.xml")
        While reader.Read()

            p = serial.Deserialize(reader)

        End While
        reader.Close()

        For Each planet In p.planet()

            If String.IsNullOrEmpty(planet.station()) = True Then

            Else

                Continue For

            End If

            If String.IsNullOrEmpty(planet.spectralClass()) = True AndAlso String.IsNullOrEmpty(planet.spectralType()) = False Then

                planet.spectralClass = planet.spectralType().Substring(0, 1)

            Else

            End If

            If String.IsNullOrEmpty(planet.spectralClass()) = True AndAlso String.IsNullOrEmpty(planet.spectralType()) = True Then

                planet.spectralClass = getSC()

            Else

            End If

            If (planet.subtype() Is Nothing) AndAlso String.IsNullOrEmpty(planet.spectralType()) = False Then

                planet.subtype = planet.spectralType().Substring(1, 1)

            Else

            End If

            If (planet.subtype() Is Nothing) AndAlso String.IsNullOrEmpty(planet.spectralType()) = True Then

                planet.subtype = getST()

            Else

            End If

            If String.IsNullOrEmpty(planet.luminosity()) = True AndAlso String.IsNullOrEmpty(planet.spectralType()) = False Then

                planet.luminosity = planet.spectralType().Substring(2, 2)

            Else

            End If

            If String.IsNullOrEmpty(planet.luminosity()) = True AndAlso String.IsNullOrEmpty(planet.spectralType()) = True Then

                planet.luminosity = getL(planet)

            Else

            End If

            If String.IsNullOrEmpty(planet.spectralType()) = True Then

                planet.spectralType = planet.spectralClass() & planet.subtype() & planet.luminosity()

            Else

            End If

            If planet.sysPos() Is Nothing Then

                planet.sysPos = getSP(planet)

            Else

            End If

            If String.IsNullOrEmpty(planet.axis()) = True Then

                planet.axis = getAxis()

            Else

            End If

            If String.IsNullOrEmpty(planet.orbit()) = True Then

                planet.orbit = getOrbit()

            Else

            End If

            If String.IsNullOrEmpty(planet.faction()) = True Then

                planet.faction = "UND"

            Else

            End If

        Next

        Dim Wsettings As XmlWriterSettings = New XmlWriterSettings()
        Wsettings.Indent = True
        Dim writer As XmlWriter = XmlWriter.Create(My.Application.Info.DirectoryPath & "\Planets\planets.xml", Wsettings)
        serial.Serialize(writer, p)
        writer.Flush()
        writer.Close()

    End Sub

    Private Function getAxis() As String

        Dim r As Integer = roll2D6()
        Select Case r

            Case 2 To 6

                Return "Tilted"

            Case 7 To 12

                Return "No Tilt"

            Case Else

                Return "Error"

        End Select

    End Function

    Private Function getOrbit() As String

        Dim r As Integer = roll2D6()
        Select Case r

            Case 2 To 6

                Return "Elliptical"

            Case 7 To 12

                Return "Circular"

            Case Else

                Return "Error"

        End Select

    End Function

    Private Function getSC() As String

        Dim r As Integer = roll2D6()
        Select Case r

            Case 2 To 4

                Return "M"

            Case 5 To 6

                Return "K"

            Case 7 To 8

                Return "G"

            Case 9 To 11

                Return "F"

            Case 12

                Return getHotStars()

            Case Else

                Return "Error"

        End Select

    End Function

    Private Function getHotStars() As String

        Dim r As Integer = roll2D6()

        If r >= 7 Then

            Return "F"

        Else

            Dim rr As Integer = roll2D6()
            Select Case rr

                Case 2 To 3

                    Return "B"

                Case 4 To 10

                    Return "A"

                Case 11

                    Return "B"

                Case 12

                    Return "F"

                Case Else

                    Return "Error"

            End Select

        End If

    End Function

    Private Function getST() As Integer

        Dim r As Integer = roll2D6()
        Select Case r

            Case 2, 12

                Return 9

            Case 3

                Return 7

            Case 4

                Return 5

            Case 5

                Return 3

            Case 6

                Return 1

            Case 7

                Return 0

            Case 8

                Return 2

            Case 9

                Return 4

            Case 10

                Return 6

            Case 11

                Return 8

            Case Else

                Return 99

        End Select

    End Function

    Private Function getL(planet) As String

        Dim r As Integer = roll2D6()

        If String.Compare(planet.SpectralClass(), "M", True) = 0 AndAlso (r = 2 OrElse r = 4) Then

            While r = 2 OrElse r = 4
                r = roll2D6()
            End While

        ElseIf String.Compare(planet.SpectralClass(), "K", True) = 0 AndAlso planet.subtype() >= 4 AndAlso r = 4 Then

            While r = 4
                r = roll2D6()
            End While

        Else

        End If

        Select Case r

            Case 2

                Return "VII"

            Case 3

                Return "VI"

            Case 4

                Return "IV"

            Case 5 To 8

                Return "V"

            Case 9

                Return "III"

            Case 10

                Return "II"

            Case 11

                Return "Ib"

            Case 12

                Return "Ia"

            Case Else

                Return "Error"

        End Select

    End Function

    Private Function getSP(planet) As Integer

        Dim table As DataTable = StarTable.starTable()
        Dim expression As String = "[Spectral Type] = " & "'" & planet.spectralType() & "'"
        Dim selectRow As DataRow()
        selectRow = table.Select(expression)
        planet.mass = selectRow(0)(1)
        planet.innerLife = selectRow(0)(2)
        planet.outerLife = selectRow(0)(4)
        getOrbitals(planet, table, expression, selectRow)
        Dim arraySlots() As Decimal = {planet.slot1(), planet.slot2(), planet.slot3(), planet.slot4(), planet.slot5(), planet.slot6(), planet.slot7(),
            planet.slot8(), planet.slot9(), planet.slot10(), planet.slot11(), planet.slot12(), planet.slot13(), planet.slot14(), planet.slot15()}
        Dim rollSlots() As Decimal = getSlots(planet)
        For i = 0 To arraySlots.Length - 1

            arraySlots(i) = rollSlots(i)

        Next

        Dim checkLife As Decimal = Array.Find(arraySlots, Function(slot)

                                                              Return slot >= planet.innerLife() AndAlso slot <= planet.outerLife()

                                                          End Function)

        If checkLife = 0 Then

            While checkLife = 0

                rollSlots = getSlots(planet)
                For i = 0 To arraySlots.Length - 1

                    arraySlots(i) = rollSlots(i)

                Next
                checkLife = Array.Find(arraySlots, Function(slot)

                                                       Return slot >= planet.innerLife() AndAlso slot <= planet.outerLife()

                                                   End Function)

            End While

        Else

        End If

        Dim p As Integer = getRandom15()
        If arraySlots(p - 1) < planet.innerLife() OrElse arraySlots(p - 1) > planet.outerLife() Then

            While arraySlots(p - 1) < planet.innerLife() OrElse arraySlots(p - 1) > planet.outerLife()

                p = getRandom15()

            End While

        End If

        Return p

    End Function

    Private Function getRandom15() As Integer

        Return r.Next(1, 16)

    End Function

    Private Sub getOrbitals(planet As Object, table As DataTable, expression As String, selectRow As DataRow())

        If (((4 / 3) ^ 2) ^ (1 / 3) * planet.mass()) > planet.outerLife() Then

            While (((4 / 3) ^ 2) ^ (1 / 3) * planet.mass()) > planet.outerLife()

                planet.spectralClass = getSC()
                planet.subtype = getST()
                planet.luminosity = getL(planet)
                planet.spectralType = planet.spectralClass() & planet.subtype() & planet.luminosity()
                expression = "[Spectral Type] = " & "'" & planet.spectralType() & "'"
                selectRow = table.Select(expression)
                planet.mass = selectRow(0)(1)
                planet.outerLife = selectRow(0)(4)

            End While

        Else

        End If

    End Sub

    Private Function getSlots(planet) As Array

        Dim Slots(14) As Decimal

        For i = 0 To Slots.Length - 1

            If i = 0 Then

                Slots(0) = getResonance() * planet.mass()

            Else

                Slots(i) = getResonance() * Slots(i - 1)

            End If

        Next

        Return Slots

    End Function

    Private Function getResonance() As Decimal

        Dim r As Integer = roll1D10()
        Select Case r

            Case 1

                Return ((4 / 3) ^ 2) ^ (1 / 3)

            Case 2

                Return ((3 / 2) ^ 2) ^ (1 / 3)

            Case 3

                Return ((8 / 5) ^ 2) ^ (1 / 3)

            Case 4

                Return ((5 / 3) ^ 2) ^ (1 / 3)

            Case 5

                Return ((7 / 4) ^ 2) ^ (1 / 3)

            Case 6

                Return ((9 / 5) ^ 2) ^ (1 / 3)

            Case 7

                Return ((2 / 1) ^ 2) ^ (1 / 3)

            Case 8

                Return ((7 / 3) ^ 2) ^ (1 / 3)

            Case 9

                Return ((5 / 2) ^ 2) ^ (1 / 3)

            Case 10

                Return ((3 / 1) ^ 2) ^ (1 / 3)

            Case Else

                Return 0

        End Select

    End Function

    Shared Function roll1D10() As Integer

        Return r.Next(1, 11)

    End Function

    Shared Function roll2D6() As Integer

        Return r.Next(1, 7) + r.Next(1, 7)

    End Function

    Public Sub New()

        serialPlanets()

    End Sub

End Class

示例planets.xml

<planets>
    <planet>
        <name>Abadan</name>
        <xcood>-70.319</xcood>
        <ycood>-95.949</ycood>
        <faction>UND</faction>
        <factionChange>
            <date>2168-01-01</date>
            <faction>TA</faction>
        </factionChange>
        <factionChange>
            <date>2242-01-01</date>
            <faction>IND</faction>
        </factionChange>
        <factionChange>
            <date>2246-01-01</date>
            <faction>MCM</faction>
        </factionChange>
        <factionChange>
            <date>2317-01-01</date>
            <faction>FWL</faction>
        </factionChange>
        <factionChange>
            <date>3014-10-15</date>
            <faction>FWLR</faction>
        </factionChange>
        <factionChange>
            <date>3014-11-03</date>
            <faction>FWL</faction>
        </factionChange>
        <factionChange>
            <date>3079-01-01</date>
            <faction>MSC</faction>
        </factionChange>
        <factionChange>
            <date>3082-01-01</date>
            <faction>ROS</faction>
        </factionChange>
        <factionChange>
            <date>3135-10-01</date>
            <faction>IND</faction>
        </factionChange>
        <factionChange>
            <date>3137-08-01</date>
            <faction>MiC</faction>
        </factionChange>
        <factionChange>
            <date>3139-07-01</date>
            <faction>CP</faction>
        </factionChange>
        <pressure>3</pressure>
        <gravity>1.03</gravity>
        <lifeForm>7</lifeForm>
        <climate>2</climate>
        <percentWater>63</percentWater>
        <temperature>22</temperature>
        <spectralClass>F</spectralClass>
        <subtype>1</subtype>
        <luminosity>V</luminosity>
        <sysPos>5</sysPos>
        <socioIndustrial>C-C-D-C-C</socioIndustrial>
        <landMass>Abadan Major (Abbasid)</landMass>
        <landMass>Abadan Minor</landMass>
        <landMass>Kuran Major</landMass>
        <landMass>Kuran Minor</landMass>
        <hpg>B</hpg>
        <desc>Abadan is a quiet world with limited military importance. The planet has a comfortable atmosphere and gravity and a cool-temperate climate. There is enough arable land on Abadan to feed the planet’s population, though there are limited natural resources to support heavy industry. The only military manufacturer on planet is Austen-Armstrong Industries and they produce personal arms located in the city of Karun on the Karun Major continent.

        Manufacturing centers:
        Austen-Armstrong Industries</desc>
    </planet>
</planets>

1 个答案:

答案 0 :(得分:1)

以下作品

<XmlRoot("landMass")>
Partial Public Class planetsPlanetLandMass

    Private landMassField As String

    'fixed
    <System.Xml.Serialization.XmlText()>
    Public landMass As String

End Class