使用 XmlReader 从 VB.NET 中的 XML 文件获取名称和值
Use XmlReader to get a name and value from an XML File in VB.NET
我正在使用以下 XML 文件和 VB 代码。我希望能够获取项目标签中的项目名称以及标签之间的任何值。获取 "Name" 值工作正常,但我似乎无法弄清楚如何读取任何子项。我想用 2 列数据填充 ListView 或者可能是 DataGrid:
project | description
------------------------
file001 | ABC Project
file002 | DEF Project
XML 文件:
<?xml version="1.0"?>
<menu>
<header>
<listname>Files list</listname>
<lastlistupdate>02/08/2018</lastlistupdate>
</header>
<project name="file001" index="true" image="'">
<description>ABC Project</description>
<month>January</month>
</project>
<project name="file002" index="true" image="'">
<description>DEF Project</description>
<month>February</month>
</project>
<project name="file003" index="true" image="'">
<description>Not really important project</description>
<month>March</month>
</project>
</menu>
此代码的奇怪之处在于 "IF" 测试通过,这意味着 xr.Name 必须是 "project"。但是,我的日志测试行 (xr.Name.ToString) 显示 .Name 是 "description"。没看懂。
Dim xmlfile As String = ""
Dim filename As String = ""
Dim title As String = ""
ListViewFiles.Items.Clear()
xmlfile = Application.StartupPath & "\projectlist.xml"
Dim xr As XmlReader = XmlReader.Create(xmlfile)
While xr.Read()
If xr.NodeType = XmlNodeType.Element AndAlso xr.Name = "project" Then
filename = xr.GetAttribute(0) 'Gets "name" correctly (ex: file001)
title = Trim(xr.ReadString()) '<<<<-- will not work
WriteLog("xr.name: " & xr.Name.ToString) <-shows the tag "description"???
ListViewFiles.Items.Add(New ListViewItem(New String() {filename, title}))
End If
End While
xr.Close()
我为您的 XML 编写了这段代码,以获取文件名 (project/name) 和标题(说明)。希望你能看懂:)
Dim filename As String = ""
Dim title As String = ""
Dim XMLReader As XmlReader = XMLReader.Create(xmlfile)
With XMLReader
'As long as the reader hasnt come to the end of the document, this loop is executed'
Do While .Read
If .IsStartElement() Then
Select Case .Name
Case "project"
filename = .GetAttribute(0)
Console.WriteLine(filename)
Case "description"
title = .ReadElementString
Console.WriteLine(title)
Console.WriteLine("Found: " & filename & " - " & title)
'you can place your "final" code here.'
Exit Select
Case Else
.Read()
'continue reading if nothing is special'
End Select
End If
Loop
.Close() 'close the reader. All done!'
End With
您可以在此处测试代码:https://dotnetfiddle.net/3CDd6Q
在您的原始代码中存在一些错误,例如您使用 xr.Name
来获取描述标签的元素,但是使用 .Name
您只能获取 <name>
标签的名称。如果要获取 <>element<>
标签之间的元素,则需要使用 .ReadElementString
。
你可以让VS做一个class对应XML文件,然后你就可以用那个class来获取数据,有时候很简单。
我将 DataGridView 放在 Form 上并使用了以下代码:
Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization
Public Class Form1
Class Project
Property Filename As String
Property Description As String
End Class
Private Sub LoadData()
Dim xmlFile = "C:\temp\projectlist.xml"
Dim projectsData As Projects.menu
Dim serializer = New XmlSerializer(GetType(Projects.menu))
Using fs As New FileStream(xmlFile, FileMode.Open, FileAccess.Read, FileShare.Read)
Using rdr = XmlReader.Create(fs)
projectsData = DirectCast(serializer.Deserialize(rdr), Projects.menu)
End Using
End Using
Dim projectsList = projectsData.project.Select(Function(p) New Project With {.Filename = p.name, .Description = p.description}).ToList()
DataGridView1.DataSource = projectsList
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadData()
DataGridView1.AutoResizeColumn(0)
DataGridView1.AutoResizeColumn(1)
End Sub
End Class
得到这个:
请根据需要调整 classes 和属性的名称。
当然,您需要 class 来配合 XML 文件。为此,复制 XML 数据,然后在 Visual Studio 中选择 "Edit"->"Paste Special"->"Paste XML as classes"。我选择将它粘贴到一个名为 "Projects" 的 class 中并得到了这个:
Public Class Projects
<System.SerializableAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True),
System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=False)>
Partial Public Class menu
Private headerField As menuHeader
Private projectField() As menuProject
'''<remarks/>
Public Property header() As menuHeader
Get
Return Me.headerField
End Get
Set
Me.headerField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlElementAttribute("project")>
Public Property project() As menuProject()
Get
Return Me.projectField
End Get
Set
Me.projectField = Value
End Set
End Property
End Class
'''<remarks/>
<System.SerializableAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class menuHeader
Private listnameField As String
Private lastlistupdateField As String
'''<remarks/>
Public Property listname() As String
Get
Return Me.listnameField
End Get
Set
Me.listnameField = Value
End Set
End Property
'''<remarks/>
Public Property lastlistupdate() As String
Get
Return Me.lastlistupdateField
End Get
Set
Me.lastlistupdateField = Value
End Set
End Property
End Class
'''<remarks/>
<System.SerializableAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class menuProject
Private descriptionField As String
Private monthField As String
Private nameField As String
Private indexField As Boolean
Private imageField As String
'''<remarks/>
Public Property description() As String
Get
Return Me.descriptionField
End Get
Set
Me.descriptionField = Value
End Set
End Property
'''<remarks/>
Public Property month() As String
Get
Return Me.monthField
End Get
Set
Me.monthField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()>
Public Property name() As String
Get
Return Me.nameField
End Get
Set
Me.nameField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()>
Public Property index() As Boolean
Get
Return Me.indexField
End Get
Set
Me.indexField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()>
Public Property image() As String
Get
Return Me.imageField
End Get
Set
Me.imageField = Value
End Set
End Property
End Class
End Class
P.S。我将编码放在 XML 文件的声明中:<?xml version="1.0" encoding="utf-8" ?>
.
我正在使用以下 XML 文件和 VB 代码。我希望能够获取项目标签中的项目名称以及标签之间的任何值。获取 "Name" 值工作正常,但我似乎无法弄清楚如何读取任何子项。我想用 2 列数据填充 ListView 或者可能是 DataGrid:
project | description
------------------------
file001 | ABC Project
file002 | DEF Project
XML 文件:
<?xml version="1.0"?>
<menu>
<header>
<listname>Files list</listname>
<lastlistupdate>02/08/2018</lastlistupdate>
</header>
<project name="file001" index="true" image="'">
<description>ABC Project</description>
<month>January</month>
</project>
<project name="file002" index="true" image="'">
<description>DEF Project</description>
<month>February</month>
</project>
<project name="file003" index="true" image="'">
<description>Not really important project</description>
<month>March</month>
</project>
</menu>
此代码的奇怪之处在于 "IF" 测试通过,这意味着 xr.Name 必须是 "project"。但是,我的日志测试行 (xr.Name.ToString) 显示 .Name 是 "description"。没看懂。
Dim xmlfile As String = ""
Dim filename As String = ""
Dim title As String = ""
ListViewFiles.Items.Clear()
xmlfile = Application.StartupPath & "\projectlist.xml"
Dim xr As XmlReader = XmlReader.Create(xmlfile)
While xr.Read()
If xr.NodeType = XmlNodeType.Element AndAlso xr.Name = "project" Then
filename = xr.GetAttribute(0) 'Gets "name" correctly (ex: file001)
title = Trim(xr.ReadString()) '<<<<-- will not work
WriteLog("xr.name: " & xr.Name.ToString) <-shows the tag "description"???
ListViewFiles.Items.Add(New ListViewItem(New String() {filename, title}))
End If
End While
xr.Close()
我为您的 XML 编写了这段代码,以获取文件名 (project/name) 和标题(说明)。希望你能看懂:)
Dim filename As String = ""
Dim title As String = ""
Dim XMLReader As XmlReader = XMLReader.Create(xmlfile)
With XMLReader
'As long as the reader hasnt come to the end of the document, this loop is executed'
Do While .Read
If .IsStartElement() Then
Select Case .Name
Case "project"
filename = .GetAttribute(0)
Console.WriteLine(filename)
Case "description"
title = .ReadElementString
Console.WriteLine(title)
Console.WriteLine("Found: " & filename & " - " & title)
'you can place your "final" code here.'
Exit Select
Case Else
.Read()
'continue reading if nothing is special'
End Select
End If
Loop
.Close() 'close the reader. All done!'
End With
您可以在此处测试代码:https://dotnetfiddle.net/3CDd6Q
在您的原始代码中存在一些错误,例如您使用 xr.Name
来获取描述标签的元素,但是使用 .Name
您只能获取 <name>
标签的名称。如果要获取 <>element<>
标签之间的元素,则需要使用 .ReadElementString
。
你可以让VS做一个class对应XML文件,然后你就可以用那个class来获取数据,有时候很简单。
我将 DataGridView 放在 Form 上并使用了以下代码:
Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization
Public Class Form1
Class Project
Property Filename As String
Property Description As String
End Class
Private Sub LoadData()
Dim xmlFile = "C:\temp\projectlist.xml"
Dim projectsData As Projects.menu
Dim serializer = New XmlSerializer(GetType(Projects.menu))
Using fs As New FileStream(xmlFile, FileMode.Open, FileAccess.Read, FileShare.Read)
Using rdr = XmlReader.Create(fs)
projectsData = DirectCast(serializer.Deserialize(rdr), Projects.menu)
End Using
End Using
Dim projectsList = projectsData.project.Select(Function(p) New Project With {.Filename = p.name, .Description = p.description}).ToList()
DataGridView1.DataSource = projectsList
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadData()
DataGridView1.AutoResizeColumn(0)
DataGridView1.AutoResizeColumn(1)
End Sub
End Class
得到这个:
请根据需要调整 classes 和属性的名称。
当然,您需要 class 来配合 XML 文件。为此,复制 XML 数据,然后在 Visual Studio 中选择 "Edit"->"Paste Special"->"Paste XML as classes"。我选择将它粘贴到一个名为 "Projects" 的 class 中并得到了这个:
Public Class Projects
<System.SerializableAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True),
System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=False)>
Partial Public Class menu
Private headerField As menuHeader
Private projectField() As menuProject
'''<remarks/>
Public Property header() As menuHeader
Get
Return Me.headerField
End Get
Set
Me.headerField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlElementAttribute("project")>
Public Property project() As menuProject()
Get
Return Me.projectField
End Get
Set
Me.projectField = Value
End Set
End Property
End Class
'''<remarks/>
<System.SerializableAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class menuHeader
Private listnameField As String
Private lastlistupdateField As String
'''<remarks/>
Public Property listname() As String
Get
Return Me.listnameField
End Get
Set
Me.listnameField = Value
End Set
End Property
'''<remarks/>
Public Property lastlistupdate() As String
Get
Return Me.lastlistupdateField
End Get
Set
Me.lastlistupdateField = Value
End Set
End Property
End Class
'''<remarks/>
<System.SerializableAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
Partial Public Class menuProject
Private descriptionField As String
Private monthField As String
Private nameField As String
Private indexField As Boolean
Private imageField As String
'''<remarks/>
Public Property description() As String
Get
Return Me.descriptionField
End Get
Set
Me.descriptionField = Value
End Set
End Property
'''<remarks/>
Public Property month() As String
Get
Return Me.monthField
End Get
Set
Me.monthField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()>
Public Property name() As String
Get
Return Me.nameField
End Get
Set
Me.nameField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()>
Public Property index() As Boolean
Get
Return Me.indexField
End Get
Set
Me.indexField = Value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()>
Public Property image() As String
Get
Return Me.imageField
End Get
Set
Me.imageField = Value
End Set
End Property
End Class
End Class
P.S。我将编码放在 XML 文件的声明中:<?xml version="1.0" encoding="utf-8" ?>
.