使用 VB.Net 读取和写入 xml 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15681403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 13:01:26  来源:igfitidea点击:

Reading and writing to an xml file with VB.Net

vb.netxml-parsing

提问by William

I am rather new to the programming world ( I'm a network guy ). I have however been asked to develop a front end that configures an xml file for a console application. The console application reads from this xml file and opens multiple instances of a browser, one instance per monitor (6 monitors in total). There are 4 control centers, each of which has 6 monitors. Each control center is run off a seperate pc. These pc's are not on the network and do not have access to each other. I have been told I can also not use a database.

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

Each monitor will display one website at a time, there could be multiple sites listed to be displayed on the specific monitor so they will periodically change. Each control center will show different sites.

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

My first question: Is this XML valid?

我的第一个问题:这个 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>

What I do so far is open the xml file and add all the monitors to a combobox

到目前为止我所做的是打开 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

This is now where I am stuck. Once the users selects one of the monitors from the combobox I then need to get all the information for that monitor. So I need the browser_short_na, and all the urls all based on the monitor_id selected.

这就是我被困的地方。一旦用户从组合框中选择了一台显示器,我就需要获取该显示器的所有信息。所以我需要browser_short_na,所有的url都基于选择的monitor_id。

I have tried creating a dataset, loading the xmlfile using readxml. I then tried creating a dataview pointing to that dataset. Tried adding a RowFilter to the dataview.

我尝试创建一个数据集,使用 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

When I step through the code and look at the for each loop it fails with the message "url_na is neither a DataColumn nor a DataRelation for table Monitor."

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

I am thinking I am not handling the url_list section correctly.

我想我没有正确处理 url_list 部分。

Once all the information for the selected monitor is read I will display the values in textboxes/listboxes which the users can then edit. If they then save it should write the new values to the xml file. They could also choose to add additional urls to the list, or even create an entirely new monitor section.

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

Any help/suggestions would be greatly appreciated.

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

采纳答案by GameAlchemist

I would go the other way around for your issue:

对于您的问题,我会反其道而行之:

  1. Define a Class (or several classes) that will hold the data you need.
  2. Use a simple serializer to load/save from/to that file.
  1. 定义一个类(或多个类)来保存您需要的数据。
  2. 使用简单的序列化程序从/向该文件加载/保存。

If you do so, then your issue with the selection is just a classical WPF issue.

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

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

MonitorsConfigurationwill then reference a List(Of Monitor)object.

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

You can use a ViewModelobject to handle a MonitorsConfigurationeasily.
This ViewModelhas a SelectedMonitorIndexproperty, and updates a UrlForThisMonitorList of url when the index property changes.
(Obviously it should implement INotifyPropertyChanged)

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

Ok so a little view on what the ViewModel might look like :

好的,关于 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

回答by Itz.Irshad

You should use XPath for parsing the XML Document.

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

  • Load the xml file in XMLDocument
  • Create a XMLNodeList and use XPath to select nodes from loaded xml
    document.
  • Then parse the nodes list and extract all info for selected monitor
    node based on id.
  • 加载 XMLDocument 中的 xml 文件
  • 创建一个 XMLNodeList 并使用 XPath 从加载的 xml
    文档中选择节点。
  • 然后解析节点列表并
    根据 id提取所选监控节点的所有信息。

Here are XPath expression helpful to you:

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

  1. For selecting monitor nodes from file: "/ControlCenter/Monitor"
  2. For selecting browser_na field based on monitor id: "/ControlCenter/Monitor[monitor_id='0']/browser_short_na"
  3. For selection urls based on monitor id: "/ControlCenter/Monitor[monitor_id='0']/url_list/url/url_na"
  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

Hope it works for you.

希望对你有效。