VB.NETでXMLを読み込む

タグの編集
投稿者 すかい  (学生) 投稿日時 2019/1/20 10:58:06
こんにちは。VB.NETでXMLを読み込み、処理する方法をネットで探したのですが目的とするものが得られませんでした。

<jishinReport>
<record date="2019年01月19日">
<item time="14時22分ごろ" shindo="2" url="#####.xml">茨城県北部</item>
<record date="2019年01月18日">
<item time="21時46分ごろ" shindo="3" url="*****.xml">千葉県北東部</item>
</record>

たとえば、このXMLで

 Dim xmlDoc As New XmlDocument()

        ' XMLを読み込み
        xmlDoc.Load("(URL)")
        Label1.Text = "最近の地震情報"
        Dim list As XmlNodeList = xmlDoc.GetElementsByTagName("item")

        For Each list2 As XmlNode In list
            Label1.Text = Label1.Text & vbCrLf & list2.Attributes("time").Value & "震度" & list2.Attributes("shindo").Value & " " & list2.InnerText
        Next

を実行すると、Label1に

最近の地震情報
14時22分ごろ 震度2 茨城県東部
21時46分ごろ 震度3 千葉県北東部

と書かれます。2019年01月19日だけのデータ(上で言うと茨城県東部の地震)を取得したいのですが、このときはどうすればいいのですか?

もし、内容に不足がありましたら付け加えます。回答お願いします。
投稿者 (削除されました)  () 投稿日時 2019/1/21 11:07:35
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/1/23 12:56:51
お使いの VBのバージョンも記載をお願いします。

現行のバージョンなら、XmlDocument を使うよりも
XDocument を使った方が簡単に書けるかもしれません。


> たとえば、このXMLで

その XML の正確なスキーマ定義を提示できますか?

例として記述して頂いたデータは、そもそもタグの数が合って無いので、
XML として認識されることは無いはずです。


とりあえず最後に閉じタグを補正してみましたが、下記の補正例だと、
18日と 19日が兄弟ノードではなく、親子ノードになってしまう点も気がかりです。

<jishinReport>
    <record date="2019年01月19日">
        <item time="14時22分ごろ" shindo="2" url="#####.xml">茨城県北部</item>
        <record date="2019年01月18日">
             <item time="21時46分ごろ" shindo="3" url="*****.xml">千葉県北東部</item>
        </record>
  </record><!-- ← 記載漏れ? -->
</jishinReport><!-- ← 記載漏れ? -->



ということは、途中に閉じタグが抜けているか…。

<jishinReport>
    <record date="2019年01月19日">
        <item time="14時22分ごろ" shindo="2" url="#####.xml">茨城県北部</item>
  </record><!-- ← 記載漏れ? -->
    <record date="2019年01月18日">
         <item time="21時46分ごろ" shindo="3" url="*****.xml">千葉県北東部</item>
    </record>
</jishinReport><!-- ← 記載漏れ? -->



もしくは、record が空要素タグであったという可能性が考えられます。

<jishinReport>
    <record date="2019年01月19日" /> <!-- ← 空要素に変更 -->
    <item time="14時22分ごろ" shindo="2" url="#####.xml">茨城県北部</item>
    <record date="2019年01月18日" /> <!-- ← 空要素に変更 -->
    <item time="21時46分ごろ" shindo="3" url="*****.xml">千葉県北東部</item>
</jishinReport><!-- ← 閉じタグ名を record から jishinReport に変更 -->



いずれにせよ、構造が変われば取得のためのコードも変更が必要なので
現状では具体的な回答を付けにくいです。正確な内容を再度確認してみてください。 
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/3/22 21:37:31
もしかして
http://www3.nhk.or.jp/sokuho/jishin/data/JishinReport.xml
のことでしょうか?

だとしたら、手っ取り早いのはこんなコード。

Public Class Form1
    Private WithEvents dataGrid1 As DataGrid
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        dataGrid1 = New DataGrid() With {.Name = "dataGrid1", .Dock = DockStyle.Fill}
        Controls.Add(dataGrid1)

        Dim ds As New DataSet()
        ds.ReadXml("http://www3.nhk.or.jp/sokuho/jishin/data/JishinReport.xml")

        dataGrid1.DataSource = ds
        dataGrid1.DataMember = "record"
    End Sub
End Class
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/3/22 22:01:37
> 2019年01月19日だけのデータ(上で言うと茨城県東部の地震)を取得したいのですが、このときはどうすればいいのですか?

最初に提示頂いたコードで言えば:
> Dim list As XmlNodeList = xmlDoc.GetElementsByTagName("item")
のところを下記のように書き換えれば OK かと。

Dim targetDate As String = "2019年01月19日"
Dim list As XmlNodeList = xmlDoc.SelectNodes("/jishinReport/record[@date='" & targetDate & "']/item")


日付で検索するのではなく、直近となる「一番上の日付」のデータを表示したいなら、こう書けます。
Dim list As XmlNodeList = xmlDoc.SelectNodes("/jishinReport/record[1]/item")


一番下にある(最古の)日付が対象なら、こう。
Dim list As XmlNodeList = xmlDoc.SelectNodes("/jishinReport/record[last()]/item")




一日に複数回の地震が発生していた場合のことを考えると、
Label に表示するよりも、Multiline = True、ReadOnly = True な TextBox とか、
あるいは、ListBox、ListView、DataGridView、DataGrid などに表示させた方が良さそうです。