如何使用Visual Basic找到XML元素的兄弟?假设我有:
<Data>
<Mail>
<Subject>Welcome!</Subject>
<From>Antonios</From>
<Content>Welcome! How can I assist you?</Content>
</Mail>
<Mail>
<Subject>Test!</Subject>
<From>John</From>
<Content>Hello Friend!</Content>
</Mail>
</Data>
现在我有一个添加每个主题的列表框,因此列表显示:欢迎!和测试! 现在我希望如此,当我点击“欢迎!”时,文本框会显示“欢迎!”“来自”元素的内容。和另一个文本框显示“欢迎”的“内容”元素。 换句话说,我正在寻找特定元素的兄弟姐妹。
答案 0 :(得分:1)
您可以通过多种方式执行此操作。以下是使用XmlDocument
和XPath:
Dim doc As New XmlDocument()
Dim From As String = doc.SelectSingleNode("/Data/Mail[Subject='Welcome!']/From").InnerText
Dim Content As String = doc.SelectSingleNode("/Data/Mail[Subject='Welcome!']/Content").InnerText
显然,由于主题可能不是唯一的,最好使用一些唯一ID的元素,或者你可以通过索引来实现。例如,这从第一封邮件消息中选择:
Dim From As String = doc.SelectSingleNode("/Data/Mail[1]/From").InnerText
但是,执行此类操作的最佳方法是将所有必需的数据预先加载到内存中。除非数据量太大,听起来不是这样,否则通常最有意义。因此,例如,我建议创建一个表示邮件消息的数据对象,例如:
Public Class Mail
Public Property Subject() As String
Get
Return _subject
End Get
Set(ByVal value As String)
_subject = value
End Set
End Property
Private _subject As String
Public Property From() As String
Get
Return _from
End Get
Set(ByVal value As String)
_from = value
End Set
End Property
Private _from As String
Public Property Content() As String
Get
Return _content
End Get
Set(ByVal value As String)
_content = value
End Set
End Property
Private _content As String
Public Overrides Function ToString() As String
Return _subject
End Function
End Class
然后,您可以为XML中的每个Mail元素加载一个Mail
对象。由于覆盖ToString
方法以显示主题,因此您可以直接将对象添加到列表框中,例如:
Dim doc As New XmlDocument()
For Each node As XmlNode In doc.SelectNodes("/Data/Mail")
Dim mail As New Mail()
mail.Subject = node.SelectSingleNode("Subject").InnerText
mail.From = node.SelectSingleNode("From").InnerText
mail.Content = node.SelectSingleNode("Content").InnerText
ListBox1.Items.Add(mail)
Next
然后,当选择列表框中的项目时,您可以将所选项目转换为Mail
类型并访问其属性,例如:
Dim mail As Mail = CType(ListBox1.SelectedItem, Mail)
Label1.Text = mail.From
Label2.Text = mail.Content
然而,在那时,如果数据不是太大,那么使用XmlSerializer
简单地将XML反序列化为对象就更容易了,例如,首先创建一个定义整个XML的类XML文档,如下所示:
Public Class Data
<XmlElement("Mail")> _
Public Property Mails() As List(Of Mail)
Get
Return _mails
End Get
Set(ByVal value As List(Of Mail))
_mails = value
End Set
End Property
Private _mails As List(Of Mail)
End Class
然后将XML加载到列表框中(其中xml
是包含XML文档的字符串):
Dim serializer As New XmlSerializer(GetType(Data))
Dim reader As New StringReader(xml)
Dim data As Data = CType(serializer.Deserialize(reader), Data)
ListBox1.Items.AddRange(data.Mails.ToArray())
或者,如果您想直接从XML文件中读取而不是从字符串反序列化它:
Dim serializer As New XmlSerializer(GetType(Data))
Using stream As New FileStream("Test.xml", FileMode.Open)
Dim data As Data = CType(serializer.Deserialize(stream), Data)
ListBox1.Items.AddRange(data.Mails.ToArray())
End Using
要回答您在下面的评论中提到的第二个问题,要删除指定的邮件,您可以这样做:
Dim node As XmlNode = doc.SelectSingleNode("/Data/Mail[Subject='Welcome!']")
node.ParentNode.RemoveChild(node)