【问题标题】:Reading and writing to an xml file with VB.Net使用 VB.Net 读取和写入 xml 文件
【发布时间】:2013-03-29 04:51:33
【问题描述】:

我对编程世界很陌生(我是网络人)。然而,我被要求开发一个为控制台应用程序配置 xml 文件的前端。控制台应用程序从这个 xml 文件中读取并打开浏览器的多个实例,每个监视器一个实例(总共 6 个监视器)。有4个控制中心,每个控制中心有6个监视器。每个控制中心都由单独的 PC 运行。这些电脑不在网络上,也无法相互访问。有人告诉我我也不能使用数据库。

每个监视器一次将显示一个网站,可能会列出多个站点以显示在特定监视器上,因此它们会定期更改。每个控制中心将显示不同的站点。

我的第一个问题:这个 XML 有效吗?

<ControlCenter>
  <Monitor>
      <monitor_id>0</monitor_id>
      <browser_short_na>ie</browser_short_na>
  <url_list>
    <url>
    <url_id>0</url_id>
    <url_na><![CDATA[http://www.hmv.com]]></url_na>
         <parameter><![CDATA[]]></parameter>
    </url>
    <url>
    <url_id>1</url_id>
    <url_na><![CDATA[http://www.amazon.com]]></url_na>
         <parameter><![CDATA[]]></parameter>
    </url>
    <url>
    <url_id>2</url_id>
    <url_na><![CDATA[http://www.google.com]]></url_na>
         <parameter><![CDATA[]]></parameter>
    </url>
 </url_list>
   </Monitor>
   <Monitor>
   <monitor_id>1</monitor_id>
   <browser_short_na>ie</browser_short_na>
    <url_list>
    <url>
            <url_id>0</url_id>
            <url_na><![CDATA[http://www.amazon.com]]></url_na>
            <parameter><![CDATA[]]></parameter>
    </url>
    </url_list>
   </Monitor>
</ControlCenter>

到目前为止,我所做的是打开 xml 文件并将所有监视器添加到组合框

 Dim dom As New Xml.XmlDocument
    dom.Load("test.xml")
    ComboBox1.Items.Clear()
    Dim monitorid As String = String.Empty
    For Each node As Xml.XmlNode In  dom.SelectNodes("//ControlCenter/Monitor/monitor_id")
        monitorid = node.InnerText
        ComboBox1.Items.Add(monitorid)
    Next

这就是我现在卡住的地方。一旦用户从组合框中选择了一个监视器,我就需要获取该监视器的所有信息。所以我需要browser_short_na,所有的url都基于选择的monitor_id。

我尝试创建一个数据集,使用 readxml 加载 xmlfile。然后我尝试创建一个指向该数据集的数据视图。尝试将 RowFilter 添加到数据视图。

Dim val As String = ComboBox1.SelectedItem.ToString

    Dim dsXmlFile As New DataSet
    dsXmlFile.ReadXml("test.xml")

Dim dv As New DataView
    dv.Table = dsXmlFile.Tables(0)

    Dim drv As DataRowView
    dv.RowFilter = "monitor_id = " & val

Dim url As String = ""
    'Retrieve my values returned in the result
    For Each drv In dv
        url = drv("url_na")
    Next

当我单步执行代码并查看 for each 循环时,它失败并显示消息“url_na 既不是 DataColumn 也不是表监视器的 DataRelation。”

我认为我没有正确处理 url_list 部分。

读取所选监视器的所有信息后,我将在文本框/列表框中显示值,然后用户可以对其进行编辑。如果他们随后保存,则应将新值写入 xml 文件。他们还可以选择在列表中添加额外的 url,甚至创建一个全新的监控部分。

任何帮助/建议将不胜感激。

【问题讨论】:

    标签: vb.net xml-parsing


    【解决方案1】:

    我会反过来解决你的问题:

    1. 定义一个类(或多个类)来保存您需要的数据。
    2. 使用简单的序列化程序从/保存到该文件。

    如果您这样做,那么您的选择问题只是一个经典的 WPF 问题。

    Public Class Monitor
        Public Property MonitorId As integer
        Public Property ListOfUrl As List(Of String)
    End Class
    

    MonitorsConfiguration 然后将引用 List(Of Monitor) 对象。

    您可以使用ViewModel 对象轻松处理MonitorsConfiguration
    这个ViewModel 有一个SelectedMonitorIndex 属性,并在索引属性更改时更新一个UrlForThisMonitor url 列表。
    (显然应该实现INotifyPropertyChanged

    好吧,稍微了解一下 ViewModel 的外观:

    Public Class MonitorsConfigurationVM
           Implement INotifyPropertyChanged
    
       ' creates a new VM. Throws exception if file name is not valid 
       Public Sub New(ConfigFileName As String)
          _FileName = ConfigFileName
          _MonitorsConfiguration = // Deserialization of the file //
          _MonitorIndex = 0 
       End Sub
    
      Public Property MonitorIndex As integer
       Get
         return _MonitorIndex
       End Get
       Set (Value)
         if (_MonitorIndex = value) then return
         ' you might want to perform check here and allow only valid index
         _MonitorIndex = value
         _UrlIndex=0
         NotifyPropertyChanged("MonitorIndex")
         NotifyPropertyChanged("MonitorUrls")
         NotifyPropertyChanged("HasUrl")
         NotifyPropertyChanged("UrlIndex")
       End Set
      End Property
    
      Public ReadOnly Property HasUrl As Boolean  
       Get
          return Not (MonitorUrls Is Nothing OrElse MonitorUrls.count = 0 )
          ' ( might be used to disable the listbox bound to MonitorUrl )
       End Get
      End Property
    
      Public ReadOnly Property MonitorUrls As List(Of String)
      Get
        return _MonitorConfiguration(_MonitorIndex).ListOfUrl  '(you might want to chk)
      End Get
      End Property
    
      Public Property UrlIndex As Integer 
      Get
         return _UrlIndex
      End Get
      Set (value)
        if value = _UrlIndex then return
        ' you might want to perform some check here
        _UrlIndex = value
        NotifyPropertyChanged("UrlIndex")
      End Set
      End Property
    
     ' And Also : AddMonitor  /   AddUrl  /  SaveConfiguration / ...
    
      Private _FileName As String = Nothing
      Private _MonitorsConfiguration As List(Of Monitor)=Nothing
      Private _MonitorIndex As integer = 0
    
       Protected Sub NotifyPropertyChanged(ByVal name As String)
           RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
       End Sub
    
       Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
    End Class
    

    【讨论】:

    • 谢谢,我试试看
    • 讨厌成为那些人中的一员,但你能给我一个代码示例来说明我将如何创建 ViewModel 对象吗?
    • 不确定你是否更新了编辑:我编辑了我的帖子顺便说一句:-)
    【解决方案2】:

    您应该使用 XPath 来解析 XML 文档。

    • 在 XMLDocument 中加载 xml 文件
    • 创建一个 XMLNodeList 并使用 XPath 从加载的 xml 中选择节点
      文件。
    • 然后解析节点列表并提取所选监视器的所有信息
      基于 id 的节点。

    以下是对您有帮助的 XPath 表达式:

    1. 用于从文件中选择监控节点:“/ControlCenter/Monitor
    2. 用于根据监视器 ID 选择 browser_na 字段:“/ControlCenter/Monitor[monitor_id='0']/browser_short_na
    3. 对于基于监​​视器 ID 的选择 URL:“/ControlCenter/Monitor[monitor_id='0']/url_list/url/url_na

    希望它对你有用。

    【讨论】:

    • 谢谢,我试试看
    猜你喜欢
    • 2015-06-12
    • 1970-01-01
    • 2012-03-04
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    相关资源
    最近更新 更多