0

I am deserializing 3,146 planets into objects, generating new values for any empty tags they may have, and then serializing them all to the writer creating a new xml document. Some of the planets have multiple landMass, satellite, and factionChange tags. My code (thank you @djv) writes out the factionChange tags correctly which all have data and faction childnodes. But landMass and Satellite continue to only print out New XML screenshot.

I have tried: (From 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

I originally had the code like this:

    <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

Which I just copied how factionChange was done since it works but, does not work for landMass and satellite.

So, the question is how to serialize and get the XmlWriter to write out multiple landMass and satellite tags (if the planet has them) to the new xml file.

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

Sample 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>
BLOODWOLF
  • 27
  • 7
  • The data your have are xml element while the code is using attributes (XmlElementAttribute). So change to XmlElement. When you serialize a class there are two ways of tagging 1)XmlRoot : Which produces one xml tag like planet 2) XmlArrayItem : Produces two xml tags like planets and planet. – jdweng Oct 23 '17 at 06:43
  • Ok I will try that when I get home. I wondered why it designated everything as XmlElementAttribute when I pasted the Xml as class but, it worked so just left it. – BLOODWOLF Oct 23 '17 at 13:13
  • No dice. Still gives me a malformed landmass tag after changing everything to XmlElement and setting the roots up correctly. Im going to try adding () to some things and hopefully get something to work. – BLOODWOLF Oct 24 '17 at 00:04

1 Answers1

1

The following works

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

    Private landMassField As String

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

End Class
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • I just figured it out *headdesk* was over complicating it. I didnt need to make a class for landMass and satellite this lists each landMass and satellite tag correctly in the new xml: Public Property satellite() As String() Public Property landMass() As String() K.I.S.S. Thank you guys for the help. – BLOODWOLF Oct 24 '17 at 01:28