0

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>

これで、すべての件名を追加するリストボックスができたので、リストには次のように表示されます。ようこそ!テスト!「ようこそ!」 をクリックすると、それが欲しいです。、テキストボックスには、 「Welcome!」の「From」要素の内容が表示されます。別のテキストボックスには、「ようこそ」の「コンテンツ」要素が表示されます。言い換えれば、私は特定の要素の兄弟を探しています。

4

1 に答える 1

1

これは複数の方法で行うことができます。XmlDocumentXPathを使用してこれを行う方法は次のとおりです。

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

Mail次に、 XMLのMail要素ごとに1つのオブジェクトをロードできます。メソッドはオーバーライドされて件名が表示されるため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ドキュメント全体を定義するクラスを作成することから始めます。

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

以下のコメントで尋ねた2番目の質問に答えるには、特定のメールメッセージを削除するには、次のようにします。

Dim node As XmlNode = doc.SelectSingleNode("/Data/Mail[Subject='Welcome!']")
node.ParentNode.RemoveChild(node)
于 2012-08-14T12:06:29.387 に答える