将新的ChildNodes添加到许多父元素

时间:2017-10-09 05:21:09

标签: xml vb.net

我有一个planets.xml文件,包含3,146个行星和每个行星的许多子节点。自上周以来,我一直在阅读教程并测试它,试图让它工作,但是,我没有得到它。我只需要知道如何添加一个新的子节点"轴"进入每个父母"星球" " ycoord"下的元素节点。然后我应该能够复制那些行星没有填充的所有其他元素(轨道,压力,百分比等)。

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<planets>
    <planet>
        <name>A Place</name>
        <xcood>-123.764</xcood>
        <ycood>272.182</ycood>
    </planet>
    <planet>
        <name>Abadan</name>
        <xcood>-70.319</xcood>
        <ycood>-95.949</ycood>
        <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>
    </planet>
    <planet>
        <name>Abagnar</name>
        <xcood>380.231</xcood>
        <ycood>314.823</ycood>
        <faction>UND</faction>
        <factionChange>
            <date>2750-01-01</date>
            <faction>DC</faction>
        </factionChange>
    </planet>
</planets>

来自planets.xml的非常短的剪辑

我的代码只是在列表的最后一个星球上添加了新标记。

Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click

    Dim xmlPlanets As XmlDocument = New XmlDocument()
    xmlPlanets.Load(My.Application.Info.DirectoryPath & "\Planets\planets.xml")
    Dim nodePlanets As XmlNodeList = xmlPlanets.GetElementsByTagName("planet")

    Dim axis As XmlElement = xmlPlanets.CreateElement("axis")
    axis.InnerText = getAxis()

    For Each node As XmlNode In nodePlanets

        If node.ChildNodes.Equals(axis) Then

        Else

            node.InsertAfter(axis, node.FirstChild)

        End If

    Next

    Dim orbit As XmlElement = xmlPlanets.CreateElement("orbit")
    orbit.InnerText = getOrbit()

    xmlPlanets.Save("planets.xml")

    Dim pressure As XmlElement = xmlPlanets.CreateElement("pressure")
    Dim gravity As XmlElement = xmlPlanets.CreateElement("gravity")
    Dim percentWater As XmlElement = xmlPlanets.CreateElement("percentWater")
    Dim temperature As XmlElement = xmlPlanets.CreateElement("temperature")
    Dim satellite As XmlElement = xmlPlanets.CreateElement("satellite")

    Dim writer As XmlTextWriter = New XmlTextWriter("planets.xml", Nothing)
    writer.Formatting = Formatting.Indented
    xmlPlanets.WriteContentTo(writer)
    writer.Flush()
    writer.Close()

    'Dim readPressure As String = nodePlanets.Item(cbPlanets.SelectedIndex).Item("pressure").InnerText
    'txtAtmosphere.Text = getPressure(readPressure)

End Sub

这仅适用于具有megamek / mekHQ的个人场景生成器项目。

2 个答案:

答案 0 :(得分:0)

我建议使用xml linq,这使得任务非常简单

Imports System.Xml
Imports System.Xml.Linq
Module Module1
    Const FILENAME As String = "c:\temp\test.xml"
    Sub Main()
        Dim doc As XDocument = XDocument.Load(FILENAME)
        Dim planets As List(Of XElement) = doc.Descendants("planet").ToList()

        For Each planet In planets
            planet.Add(New XElement("axis", 123))
        Next planet

    End Sub

End Module

答案 1 :(得分:0)

我会从xml创建一个类。在您执行此操作之前,请如上所示获取xml的示例,并将轴节点添加到任何一个行星节点。然后在visual studio中,编辑&gt;&gt;将Xml粘贴为类。它会创建你的模型。

XML:

<planets>
  <planet>
    <name>A Place</name>
    <xcood>-123.764</xcood>
    <ycood>272.182</ycood>
  </planet>
  <planet>
    <name>Abadan</name>
    <xcood>-70.319</xcood>
    <ycood>-95.949</ycood>
    <axis>some string</axis> <!--added this-->
    <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>
  </planet>
  <planet>
    <name>Abagnar</name>
    <xcood>380.231</xcood>
    <ycood>314.823</ycood>
    <faction>UND</faction>
    <factionChange>
      <date>2750-01-01</date>
      <faction>DC</faction>
    </factionChange>
  </planet>
</planets>

生成的类:

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True),
    System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=False)>
Partial Public Class planets

    Private planetField() As planetsPlanet

    '''<remarks/>
    <System.Xml.Serialization.XmlElementAttribute("planet")>
    Public Property planet() As planetsPlanet()
        Get
            Return Me.planetField
        End Get
        Set
            Me.planetField = Value
        End Set
    End Property
End Class

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanet

    Private nameField As String

    Private xcoodField As Decimal

    Private ycoodField As Decimal

    Private factionField As String

    Private factionChangeField As planetsPlanetFactionChange

    Private axisField As String

    Private pressureField As Byte

    Private pressureFieldSpecified As Boolean

    Private gravityField As Decimal

    Private gravityFieldSpecified As Boolean

    Private lifeFormField As Byte

    Private lifeFormFieldSpecified As Boolean

    Private climateField As Byte

    Private climateFieldSpecified As Boolean

    Private percentWaterField As Byte

    Private percentWaterFieldSpecified As Boolean

    Private temperatureField As Byte

    Private temperatureFieldSpecified As Boolean

    Private spectralClassField As String

    Private subtypeField As Byte

    Private subtypeFieldSpecified As Boolean

    Private luminosityField As String

    Private sysPosField As Byte

    Private sysPosFieldSpecified As Boolean

    Private socioIndustrialField As String

    Private landMassField() As String

    Private hpgField As String

    '''<remarks/>
    Public Property name() As String
        Get
            Return Me.nameField
        End Get
        Set
            Me.nameField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property xcood() As Decimal
        Get
            Return Me.xcoodField
        End Get
        Set
            Me.xcoodField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property ycood() As Decimal
        Get
            Return Me.ycoodField
        End Get
        Set
            Me.ycoodField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property faction() As String
        Get
            Return Me.factionField
        End Get
        Set
            Me.factionField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property factionChange() As planetsPlanetFactionChange
        Get
            Return Me.factionChangeField
        End Get
        Set
            Me.factionChangeField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property axis() As String
        Get
            Return Me.axisField
        End Get
        Set
            Me.axisField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property pressure() As Byte
        Get
            Return Me.pressureField
        End Get
        Set
            Me.pressureField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property pressureSpecified() As Boolean
        Get
            Return Me.pressureFieldSpecified
        End Get
        Set
            Me.pressureFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property gravity() As Decimal
        Get
            Return Me.gravityField
        End Get
        Set
            Me.gravityField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property gravitySpecified() As Boolean
        Get
            Return Me.gravityFieldSpecified
        End Get
        Set
            Me.gravityFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property lifeForm() As Byte
        Get
            Return Me.lifeFormField
        End Get
        Set
            Me.lifeFormField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property lifeFormSpecified() As Boolean
        Get
            Return Me.lifeFormFieldSpecified
        End Get
        Set
            Me.lifeFormFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property climate() As Byte
        Get
            Return Me.climateField
        End Get
        Set
            Me.climateField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property climateSpecified() As Boolean
        Get
            Return Me.climateFieldSpecified
        End Get
        Set
            Me.climateFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property percentWater() As Byte
        Get
            Return Me.percentWaterField
        End Get
        Set
            Me.percentWaterField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property percentWaterSpecified() As Boolean
        Get
            Return Me.percentWaterFieldSpecified
        End Get
        Set
            Me.percentWaterFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property temperature() As Byte
        Get
            Return Me.temperatureField
        End Get
        Set
            Me.temperatureField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property temperatureSpecified() As Boolean
        Get
            Return Me.temperatureFieldSpecified
        End Get
        Set
            Me.temperatureFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property spectralClass() As String
        Get
            Return Me.spectralClassField
        End Get
        Set
            Me.spectralClassField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property subtype() As Byte
        Get
            Return Me.subtypeField
        End Get
        Set
            Me.subtypeField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property subtypeSpecified() As Boolean
        Get
            Return Me.subtypeFieldSpecified
        End Get
        Set
            Me.subtypeFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property luminosity() As String
        Get
            Return Me.luminosityField
        End Get
        Set
            Me.luminosityField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property sysPos() As Byte
        Get
            Return Me.sysPosField
        End Get
        Set
            Me.sysPosField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlIgnoreAttribute()>
    Public Property sysPosSpecified() As Boolean
        Get
            Return Me.sysPosFieldSpecified
        End Get
        Set
            Me.sysPosFieldSpecified = Value
        End Set
    End Property

    '''<remarks/>
    Public Property socioIndustrial() As String
        Get
            Return Me.socioIndustrialField
        End Get
        Set
            Me.socioIndustrialField = Value
        End Set
    End Property

    '''<remarks/>
    <System.Xml.Serialization.XmlElementAttribute("landMass")>
    Public Property landMass() As String()
        Get
            Return Me.landMassField
        End Get
        Set
            Me.landMassField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property hpg() As String
        Get
            Return Me.hpgField
        End Get
        Set
            Me.hpgField = Value
        End Set
    End Property
End Class

'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class planetsPlanetFactionChange

    Private dateField As Date

    Private factionField As String

    '''<remarks/>
    <System.Xml.Serialization.XmlElementAttribute(DataType:="date")>
    Public Property [date]() As Date
        Get
            Return Me.dateField
        End Get
        Set
            Me.dateField = Value
        End Set
    End Property

    '''<remarks/>
    Public Property faction() As String
        Get
            Return Me.factionField
        End Get
        Set
            Me.factionField = Value
        End Set
    End Property
End Class

现在,这个类很容易使用,因为你有.NET类而不是尝试导航xml文件。我建议使用xml序列化将xml加载到.NET对象中:

Imports System.Xml.Serialization
Imports System.IO

Module Module1

    Sub Main()
        Dim s As New XmlSerializer(GetType(planets))
        Dim p As planets
        ' load the xml file
        Using fs As New FileStream("planets.xml", FileMode.Open)
            p = s.Deserialize(fs)
        End Using
        ' operations on the planet objects
        For Each planet In p.planet
            planet.axis = "new value"
        Next
        ' overwrite the xml file
        Using fs As New FileStream("planets.xml", FileMode.Truncate)
            s.Serialize(fs, p)
        End Using
    End Sub

End Module

如您所见,此代码会将每个行星的轴设置为“新值”。当然,您可以将其设置为您想要的任何内容,因为在每个循环中,您可以访问行星的所有其他属性。不将它们视为xml节点使它们更容易使用。

注意:Visual Studio的将XML作为类很好,但是如果你的字符串实际上应该只限于几个值,那么最好让它们成为枚举(如果没有你的介入,生成器就不可能知道) 。您应该修改生成的类或模型,以使其更准确地表示您的数据。