【问题标题】:VB.net XML Get a group of nodes Attributes and group them by node?VB.net XML 获取一组节点属性并按节点分组?
【发布时间】:2014-10-23 20:02:29
【问题描述】:

我的 XML 文件如下所示

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <mob name="mob1" lvl="5" hp="30" mp="25"/>
  <mob name="mob2" lvl="6" hp="50" mp="55"/>
  <mob name="mob3" lvl="9" hp="80" mp="85"/>
  <mob name="mob4" lvl="11" hp="130" mp="125"/>
</root>

我对编程和开发一个可以列出和跟踪数据的程序相当陌生。 我想要做的是用“名称”属性中的条目填充一个组合框,当您在组合框中选择条目时,它将从同一节点中提取 Lvl、hp、mp 属性并将它们放入一些要使用和显示的变量。

我的工作方式是使用这样的 XML 文件

    <?xml version="1.0" encoding="utf-8" ?>
<root>
  <moblist list="mob1,mob2,mob3,mob4"/>
  <mob0 lvl="5" hp="30" mp="25"/>
  <mob1 lvl="6" hp="50" mp="55"/>
  <mob2 lvl="9" hp="80" mp="85"/>
  <mob3 lvl="11" hp="130" mp="125"/>
</root>

将 moblist 节点列表属性转换为列表,并使用它来填充组合框。 然后做这样的事情:

    newindex = cmb_mobs.SelectedIndex
    index = "/root/mob" & newindex
    Dim doc As XmlDocument = New XmlDocument()
    doc.Load("C:/test.xml")
    Dim root As XmlNode = doc.DocumentElement
    Dim mobs As XmlNode
    mobs = root.SelectSingleNode(index)
    Dim shw_lvl As String = mobs.Attributes.ItemOf("lvl").InnerText
    Dim shw_hp As String = mobs.Attributes.ItemOf("hp").InnerText
    Dim shw_mp As String = mobs.Attributes.ItemOf("mp").InnerText

每次组合框选择的索引更改时,我都会让它消失。

问题 1:有没有更好的方法来实现这些结果?如果可以做得更好,我愿意更改 xml 结构。

【问题讨论】:

  • 一般来说:你真的不应该有“编号”的 XML 元素。如果有多个 mob 实例,它们都应该是 &lt;mob&gt;,而不是 &lt;mob1&gt;&lt;mobN&gt;。改为使用 id 属性。 (我也不确定&lt;moblist&gt; 的目的是什么。它在 XML 的结构中,不需要保留显式列表,还是存在?)
  • 另外,如果没有看到您的其余代码,回答问题 2 并不容易。一种方法是在应用程序启动时加载 XML 文件,并在每次需要时使用内存中的实例它。
  • 这是我能想出让它做我想做的事情的唯一方法,我将如何填充一个带有 'id' 属性的 ComboBox,然后当我在 ComboBox 中选择一个项目时它从与所选 id 相同的节点中获取所有其他属性并将它们放入变量中?
  • ComboBox 可以包含任意对象的列表,它们不必是字符串。例如,您可以在 XmlNode 对象上使用 ComboBox。比较 ComboBox.Items Property 上的 MSDN 文章。您也可以使用自定义 Mob 对象,就像 Neolisk 的回答所建议的那样。或者您使用XML-to-object de-serialization 直接从您的 XML 构建自定义对象。

标签: xml vb.net


【解决方案1】:

可以使用xml序列化。

使用这个 xml 文件,

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <mob name="mob1" lvl="5" hp="30" mp="25"/>
  <mob name="mob2" lvl="6" hp="50" mp="55"/>
  <mob name="mob3" lvl="9" hp="80" mp="85"/>
  <mob name="mob4" lvl="11" hp="130" mp="125"/>
</root>

在VB中这样定义xml模型

Imports System.Xml.Serialization
Imports System.IO
<XmlRoot("root")>
Public Class XmlModel
    <XmlElement("mob")>
    Public Property Mobs As List(Of XmlMob)
End Class

<Serializable>
Public Class XmlMob
    <XmlAttribute("name")>
    Public Property Name As String
    <XmlAttribute("lvl")>
    Public Property Level As Integer
    <XmlAttribute("hp")>
    Public Property HitPoints As Integer
    <XmlAttribute("mp")>
    Public Property MagicPoints As Integer
End Class

然后将xml文件反序列化为XmlModel类的实例

Private xmlMobs As XmlModel

Private Sub LoadXmlFile()
    Dim s As New XmlSerializer(GetType(XmlModel))
    Using sr As New StreamReader("c:/test.xml")
        xmlMobs = s.Deserialize(sr)
    End Using
End Sub

现在你有了一个变量xmlMobs,它保存了你所有的生物信息。然后您可以修改此变量(更改名称、统计信息等),并序列化回文件中。

Private Sub SaveXmlFile()
    Dim s As New XmlSerializer(GetType(XmlModel))
    Using sw As New StreamWriter("c:/test.xml")
        s.Serialize(sw, xmlMobs)
    End Using
End Sub

【讨论】:

  • 我认为您必须包含一个适用于这种方法的 XML 示例。 (还有一种将它绑定到 ComboBox 的方法,当你在它的时候。)
  • @Tomalak 我使用了 OP 问题中的示例。为了清楚起见,我将在此处添加它。
【解决方案2】:

您可以将 XML 缓存在内存中,如下所示:

Dim xml = <?xml version="1.0" encoding="utf-8"?>
          <root>
            <mob name="mob1" lvl="5" hp="30" mp="25"/>
            <mob name="mob2" lvl="6" hp="50" mp="55"/>
            <mob name="mob3" lvl="9" hp="80" mp="85"/>
            <mob name="mob4" lvl="11" hp="130" mp="125"/>
          </root>

Dim mobs As New List(Of Mob)
For Each e As XElement In xml.Root.Elements
  Dim m As New Mob
  m.name = e.Attribute("name").Value
  m.lvl = e.Attribute("lvl").Value
  m.hp = e.Attribute("hp").Value
  m.mp = e.Attribute("mp").Value
  mobs.Add(m)
Next

假设以下类 Mob:

Class Mob
  Public Property name As String
  Public Property lvl As String
  Public Property hp As String
  Public Property mp As String

  Public Overrides Function ToString() As String
    Return Me.name
  End Function
End Class

然后使用数据绑定来填充您的组合框:

comboBox1.DataSource = mobs

然后在 SelectedIndexChanged 事件中,从选定的 Mob 中提取并显示您需要的数据:

Dim m As Mob = DirectCast(comboBox1.SelectedItem, Mob)
Dim shw_lvl As String = m.lvl
Dim shw_hp As String = m.hp
Dim shw_mp As String = m.mp

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    相关资源
    最近更新 更多