将XmlAttribute添加到可序列化对象的许多XmlElements

时间:2017-11-29 04:52:44

标签: xml vb.net generics serialization

我需要在我的planets.xml中为每个行星的45个字段中的大约30个字段添加一个XmlAttribute(" isCanon = true / false")。我已手动将属性添加到一个星球的所有字段,并将其保存为test.xml,然后将xml粘贴为类,但它不会生成工作代码。我得到一个" InvalidOperationException:无法序列化成员' isCanon' System.Object类型。 XmlAttribute / XmlText不能用于编码复杂类型。"我也尝试使用泛型来做这个,所以我不必为Planet的每个字段制作30-45个新类(我不知道泛型是否是正确的方法来执行此操作)。

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

    Private a As Boolean
    Private i As T

    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property isCanon()
    <System.Xml.Serialization.XmlTextAttribute()>
    Public Property inner()

End Class

当我为x坐标元素粘贴测试xml的类时,这就是visual studio生成的内容:

Partial Public Class planetsPlanet

    Private xcoodField As planetsPlanetXcood

    Public Property xcood() As planetsPlanetXcood
        Get
            Return Me.xcoodField
        End Get
        Set
            Me.xcoodField = Value
        End Set
    End Property

End Class

Partial Public Class planetsPlanetXcood

    Private isCanonField As Boolean

    Private valueField As Decimal

    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>
    Public Property isCanon() As Boolean
        Get
            Return Me.isCanonField
        End Get
        Set
            Me.isCanonField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlTextAttribute()>
    Public Property Value() As Decimal
        Get
            Return Me.valueField
        End Get
        Set
            Me.valueField = Value
        End Set
    End Property
End Class

这是我的简化planets.xml,其中只有一个行星用于测试(原始的planets.xml包含超过3,000个行星,这些行星被序列化为对象,经过修改,然后写入新的planets.xml)。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- This file is for testing the planets -->
<planets>
    <planet>
        <xcood isCanon="true">-123.764</xcood>
        <ycood isCanon="true">272.182</ycood>
        <id isCanon="true">A Place</id>
        <name isCanon="true">A Place</name>
        <sysPos isCanon="false">3</sysPos>
        <spectralType isCanon="true">K1V</spectralType>
        <spectralClass isCanon="true">K</spectralClass>
        <subtype isCanon="true">1.0</subtype>
        <luminosity isCanon="true">V</luminosity>
        <orbitRadius isCanon="false">1.00000011</orbitRadius>
        <orbitEccentricity isCanon="false">0.0167086</orbitEccentricity>
        <orbitInclination isCanon="false">1.57869</orbitInclination>
        <satellite isCanon="false">Moon</satellite>
        <gravity isCanon="false">1.0</gravity>
        <dayLength isCanon="false">24.0</dayLength>
        <percentWater isCanon="false">75</percentWater>
        <volcanism isCanon="false">2</volcanism>
        <tectonics isCanon="false">2</tectonics>
        <landMass isCanon="false">Asia</landMass>
        <landMass isCanon="false">Africa</landMass>
        <landMass isCanon="false">Antarctica</landMass>
        <landMass isCanon="false">Australia</landMass>
        <landMass isCanon="false">Europe (Geneva)</landMass>
        <landMass isCanon="false">North America</landMass>
        <landMass isCanon="false">South America</landMass>
        <landMass isCanon="false">Mars - (Koryo)</landMass>
        <landMass isCanon="false">Luna - (Luna City)</landMass>
        <nadirCharge isCanon="false">false</nadirCharge>
        <zenithCharge isCanon="false">false</zenithCharge>
        <pressure isCanon="false">3</pressure>
        <pressureAtm isCanon="false">1.0</pressureAtm>
        <atmMass isCanon="false">1.0</atmMass>
        <albedo isCanon="false">0.33</albedo>
        <greenhouse isCanon="false">1.0</greenhouse>
        <temperature isCanon="false">30</temperature>
        <climate isCanon="false">TEMPERATE</climate>
        <lifeForm isCanon="false">MAMMAL</lifeForm>
        <habitability isCanon="false">7</habitability>
        <pop isCanon="false">10</pop>
        <government isCanon="false">Democracy (Representative)</government>
        <controlRating isCanon="false">5</controlRating>
        <socioIndustrial isCanon="true">C-C-A-C-D</socioIndustrial>
        <hpg isCanon="false">A</hpg>
        <faction isCanon="true">UND</faction>
        <desc>Despite A Place's poor soil making agriculture nearly impossible the planet was settled to take advantage of its abundance of natural resources. For most of its history A Place has relied on its neighbor, Bountiful Harvest for food. Unfortunately, when there are disruptions in shipping, such as during the 1st Succession War, food shortages begin almost immediately. During the 1st Succession War the lack of food resulted in nearly 90% of the planet's million inhabitants starving.</desc>
        <event>
            <date isCanon="true">2235-01-01</date>
            <faction isCanon="true">IND</faction>
        </event>
        <event>
            <date isCanon="true">2571-01-01</date>
            <faction isCanon="true">LA</faction>
        </event>
        <event>
            <date isCanon="true">3040-01-19</date>
            <faction isCanon="true">FC</faction>
        </event>
        <event>
            <date isCanon="true">3057-12-01</date>
            <faction isCanon="true">ARDC</faction>
        </event>
        <event>
            <date isCanon="true">3067-04-24</date>
            <faction isCanon="true">LA</faction>
        </event>
        <event>
            <date isCanon="true">3130-01-01</date>
            <faction isCanon="true">CJF,LA</faction>
        </event>
        <event>
            <date isCanon="true">3135-01-01</date>
            <faction isCanon="true">CJF</faction>
        </event>
    </planet>
</planets>

实际序列化的类的一部分,如果行星没有填充所有内容,则会生成缺失数据,然后编写新的planets.xml

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()

    Dim Wsettings As XmlWriterSettings = New XmlWriterSettings With {
    .Indent = True,
    .IndentChars = (ControlChars.Tab),
    .ConformanceLevel = ConformanceLevel.Document,
    .WriteEndDocumentOnClose = True}

    For Each planet In p.planetArray()
    'tons of stuff to generate various planet attributes
    Next

    Array.Sort(p.planetArray)
    Dim writer As XmlWriter = XmlWriter.Create(My.Application.Info.DirectoryPath & "\Planets\planets.xml", Wsettings)
    serial.Serialize(writer, p)
    writer.Flush()
    writer.Close()

End Sub

我的代码的完整示例可以在我的github PlanetsXML上找到,问题主要涉及Planets.vb和objPlanets.vb。

0 个答案:

没有答案