3

私はプログラミングの世界ではかなり新しいです (私はネットワーク担当者です)。しかし、コンソール アプリケーション用の xml ファイルを構成するフロント エンドの開発を依頼されました。コンソール アプリケーションは、この xml ファイルから読み取り、ブラウザーの複数のインスタンス (モニターごとに 1 つのインスタンス (合計 6 つのモニター)) を開きます。4 つのコントロール センターがあり、それぞれに 6 つのモニターがあります。各コントロール センターは、個別の PC から実行されます。これらの PC はネットワーク上になく、相互にアクセスできません。データベースも使用できないと言われました。

各モニターは一度に 1 つの Web サイトを表示します。特定のモニターに表示される複数のサイトがリストされている可能性があるため、サイトは定期的に変更されます。各コントロール センターには異なるサイトが表示されます。

私の最初の質問: この 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

これは私が立ち往生しているところです。ユーザーがコンボボックスからモニターの 1 つを選択したら、そのモニターのすべての情報を取得する必要があります。したがって、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 はテーブル Monitor の DataColumn でも DataRelation でもありません」というメッセージが表示されて失敗します。

url_list セクションを正しく処理していないと考えています。

選択したモニターのすべての情報が読み取られたら、ユーザーが編集できるテキストボックス/リストボックスに値を表示します。その後保存すると、新しい値が xml ファイルに書き込まれます。リストに追加の URL を追加したり、まったく新しい監視セクションを作成したりすることもできます。

どんな助け/提案も大歓迎です。

4

2 に答える 2

0

XML ドキュメントの解析には XPath を使用する必要があります。

  • 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にはプロパティがあり、インデックス プロパティが変更されたときに URLSelectedMonitorIndexのリストを更新します。 (明らかに実装する必要があります)UrlForThisMonitor
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 に答える