【问题标题】:Add new ChildNodes to many parent elements向许多父元素添加新的 ChildNode
【发布时间】:2017-10-09 05:21:09
【问题描述】:

我有一个 planets.xml 文件,其中包含 3,146 个行星和每个行星的许多子节点。自上周以来,我一直在阅读教程并对其进行测试,试图让它发挥作用,但我没有得到它。我只需要知道如何在“ycoord”节点下的每个父“planet”元素中添加一个新的子节点“axis”。然后我应该能够为一些行星没有填写的所有其他元素(轨道、压力、水百分比等)复制它。

    <?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 的个人场景生成器项目。

【问题讨论】:

    标签: xml vb.net


    【解决方案1】:

    我会从 xml 创建一个类。在您执行此操作之前,请按照上面的方式获取 xml 样本,并将轴节点添加到任何一个行星节点。然后在 Visual Studio 中,编辑 >> 将 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
    

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

    注意:Visual Studio 的将 XML 粘贴为类非常棒,但如果您的字符串确实应该限制为几个值,则最好将它们设为枚举(如果没有您的干预,生成器不可能知道) .您应该修改生成的类或模型,使其更准确地表示您的数据。

    【讨论】:

    • 啊哈,这正是我所需要的。网络上的所有示例和教程都只是针对只有一个父级(在我的例子中是行星)的 xml,并且对于如何使其以自动化方式为 3000 个行星工作存在心理障碍。
    • 好的,我正在使用 Visual Studio 2017 框架 4.7。#### 并且我没有得到编辑>复制我的 xml 文本后的特殊粘贴,光标在我已经拥有并尝试过新模块>代码文件。我想知道他们是否改变了什么。
    • 那是我做的时候用的那个版本。
    • 用谷歌搜索并确保我的目标框架超过 4.5(是 .NET 4.6.1)并用谷歌搜索了更多,发现我没有安装 WCF(不知道那是什么)。 ...我在学。现在粘贴为类很整洁。
    • 好的,与您的示例代码相比,它以完全不同的方式/格式将 xml 作为类粘贴到 planetsPlanet。它创建了一个作为 Object 的 itemsField,作为 Enum 的 itemsElementName,作为字符串的 textField。使用整个 &lt;System.Xml.Serialization.XmlElementAttribute("axis", GetType(String)), 表,然后为三个变量中的每一个变量设置一个 get 和 set 属性。但是,我不知道如何用它来设置轴的值,所以会重写它在你的示例中所做的。
    【解决方案2】:

    我建议使用 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
    

    【讨论】:

      猜你喜欢
      • 2019-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      • 2013-10-31
      • 2018-12-10
      • 1970-01-01
      • 2018-12-03
      相关资源
      最近更新 更多