3

我对编程世界相当陌生(我是网络人)。然而,我被要求开发一个为控制台应用程序配置 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,甚至创建一个全新的监控部分。

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

4

2 回答 2

0

您应该使用 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

希望对你有效。

于 2013-03-28T12:42:25.403 回答
0

对于您的问题,我会反过来:

  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属性,并在索引属性更改时更新一个UrlForThisMonitorurl 列表。
(显然它应该实现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
于 2013-03-28T12:42:48.773 回答