ここでは XML 形式のファイルの入出力を説明します。
言語は VB.NET です。
画面(WindowsForm)に表示するために、DataGridView を使っています。
XML ファイルを読み込み、DataGridView に表示し、それを XML ファイルに書き出しています。
DataGridView は先頭列でソートしできるので、書き出した結果が元と違っているのが分かります。
なお、このサンプルは MSDN フォーラムでの問い合わせ対応用に作ったものです。
元の XML ファイル(Family.xml)を Excel で開くと次のように見えます。
テキストエディターで開くと、こんな感じ・・・
1列目がファーストネーム、2列目がラストネーム、3列目が電話番号です。
サンプルを実行するとこのようになります。
1.XML ファイルをインポートし DataGridView に格納
2.ファーストネームでソート
3.それを XML ファイルにエクスポート
さて、画面とコードは次のとおりです。
メインフォームの画像:
メインフォームのコード:
-------------------------------------------------------------------
Public Class frm_Main
#Region "=== Form: Load, Closing"
Private Sub frm_Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call cls_DGV.prc_Prepare_dgv_Family()
End Sub
#End Region
#Region "=== [Button]"
--[Import] buttn: Read XML and store data to DGV
Private Sub btn_OpenFile_Click(sender As Object, e As EventArgs) Handles btn_Import.Click
With Me.OpenFileDialog1
.InitialDirectory = System.Reflection.Assembly.GetExecutingAssembly().Location
.Title = "Select an XML file"
.Filter = "XML file (*.xml)|*.xml"
End With
If (Me.OpenFileDialog1.ShowDialog = DialogResult.OK) Then
Me.txt_InputFileName.Text = Me.OpenFileDialog1.FileName
Call Me.prc_Create_OutputFileName(Me.OpenFileDialog1.FileName)
Call cls_DGV.prc_Clear_dgv_Family()
Call cls_FileIO.prc_Read_File()
Me.dgv_Family.ClearSelection()
End If
End Sub
' --- decide output file name: addding "_Sorted" to original name
Private Sub prc_Create_OutputFileName(ByVal inputFileName As String)
' --- decide file name WithOut Path
Dim fileNameWOPath As String = System.IO.Path.GetFileName(inputFileName)
Dim extension As String = System.IO.Path.GetExtension(inputFileName)
fileNameWOPath = fileNameWOPath.Replace(extension, "_Sorted.xml")
' --- decide file name with Path
Dim dirName As String = System.IO.Path.GetDirectoryName(inputFileName)
Me.txt_OutputFileName.Text = dirName & "\" & fileNameWOPath
End Sub
' ---[Sort] button
Private Sub btn_Sort_Click(sender As Object, e As EventArgs) Handles btn_Sort.Click
' --- sort columns(0): f_name -- ascending
Me.dgv_Family.Sort(dgv_Family.Columns(0), System.ComponentModel.ListSortDirection.Ascending)
Me.dgv_Family.ClearSelection()
End Sub
' ---[Export] button: Write XML using DGV data
Private Sub btn_Export_Click(sender As Object, e As EventArgs) Handles btn_Export.Click
Call cls_FileIO.prc_Write_File()
If (MessageBox.Show _
("Export completed." & Chr(13) & "Open the exported file?", "Open?", MessageBoxButtons.YesNo) _
= DialogResult.Yes) Then
Dim p As System.Diagnostics.Process _
= System.Diagnostics.Process.Start(Me.txt_OutputFileName.Text)
End If
End Sub
#End Region
End Class
-------------------------------------------------------------------
cls_DGV のコード:
・・・メインフォーム上の DataGridView(dgv_Family)を定義する処理と
DataGridView をクリアする処理です。
-------------------------------------------------------------------
Public Class cls_DGV
Inherits frm_Main
' --- Prepare dgv_Family
Public Sub prc_Prepare_dgv_Family()
With frm_Main.dgv_Family
.ColumnHeadersHeight = 30 ' -- 列見出しの高さ
.RowTemplate.Height = 30 ' -- 行の高さ
.RowHeadersVisible = False ' -- ● 左端のレコードセレクターは非表示
.MultiSelect = False ' -- 複数選択は不可
.AllowUserToAddRows = False ' -- 行の追加禁止(末尾の新規行を表示しない)
.AllowUserToResizeColumns = True ' -- 列幅変更を許可
.BackgroundColor = Color.WhiteSmoke ' -- 背景色
.AlternatingRowsDefaultCellStyle.BackColor = Color.WhiteSmoke ' -- 1行おきの色
.SelectionMode = DataGridViewSelectionMode.FullRowSelect ' -- 選択は行全体
' --- ヘッダーの背景色
.EnableHeadersVisualStyles = False ' -- これが必要
.ColumnHeadersDefaultCellStyle.BackColor = Color.Gainsboro
.RowHeadersDefaultCellStyle.BackColor = Color.Gainsboro
' --- 列幅(初期値として)
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
.Columns(0).FillWeight = 30 ' -- f_name
.Columns(1).FillWeight = 30 ' -- l_name
.Columns(2).FillWeight = 40 ' -- tel
' --- 文字位置(ヘッダーはすべて中央揃え)
For idx As Integer = 0 To .Columns.Count - 1
.Columns(idx).HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter
Next
End With
End Sub
' --- Clear dgv_Family: delete all rows
Public Sub prc_Clear_dgv_Family()
For r As Integer = 0 To frm_Main.dgv_Family.Rows.Count - 1
frm_Main.dgv_Family.Rows.RemoveAt(0)
Next
End Sub
End Class
-------------------------------------------------------------------
一番大事なファイル入出力のコード:
-------------------------------------------------------------------
Imports System.Xml ' -- XML
Public Class cls_FileIO
Inherits frm_Main
#Region "=== Variables"
private xmlWtr As System.Xml.XmlTextWriter
Private Col_0, Col_1, Col_2 As String
Private maxCol As Integer = 2 ' -- last column index to export
#End Region
#Region "=== Read XML"
' --- Import from XML
Public Sub prc_Read_File()
If (System.IO.File.Exists(frm_Main.txt_InputFileName.Text) = False) Then
MessageBox.Show("File does not exist." & Chr(13) & frm_Main.txt_InputFileName.Text)
Exit Sub ' --▶ 処理を抜ける
End If
' --- load XML file: XmlTextReader
Dim xmlRdr As New XmlTextReader(frm_Main.txt_InputFileName.Text)
Dim myRow As Integer = 0
' --- Read XML file
While xmlRdr.Read()
If (xmlRdr.NodeType = XmlNodeType.Element) Then
' frm_Main.dgv_Family.Rows.Add() ' --◀ add row in DGV
' ---
Select Case xmlRdr.Name
Case = "f_name"
frm_Main.dgv_Family.Rows.Add() ' --◀ add Row in DGV
frm_Main.dgv_Family(0, myRow).Value = xmlRdr.ReadString()
Case = "l_name"
frm_Main.dgv_Family(1, myRow).Value = xmlRdr.ReadString()
Case = "tel"
frm_Main.dgv_Family(2, myRow).Value = xmlRdr.ReadString()
myRow += 1 ' --◀ add Row index
End Select
End If
End While
' --- post process
xmlRdr.Close()
xmlRdr.Dispose()
End Sub
#End Region
#Region "=== Write XML"
' --- Export to XML
Public Sub prc_Write_File()
' --- create instance of XML Writer
xmlWtr = New XmlTextWriter(frm_Main.txt_OutputFileName.Text, System.Text.Encoding.UTF8)
' --- output XML definition
xmlWtr.WriteStartDocument(True)
xmlWtr.Formatting = Formatting.Indented
xmlWtr.Indentation = 4
xmlWtr.WriteStartElement("Hokusosha") ' -- Space is not permitted
' --- dgv_Family: Loop by Rows
Dim myRow As Integer
For myRow = 0 To frm_Main.dgv_Family.RowCount - 1
Call Me.prc_XML_Null_Handling(myRow) ' -- Null handling
xmlWtr.WriteStartElement("Line")
Call Me.sub_CreateNode _
(Col_0, Col_1, Col_2, xmlWtr) ' -- create node (columns 0-2)
xmlWtr.WriteEndElement()
Next
' --- post process
xmlWtr.WriteEndElement()
xmlWtr.WriteEndDocument()
xmlWtr.Flush() ' -- settle
xmlWtr.Close() ' -- close
xmlWtr.Dispose() ' -- release from memory
End Sub
' --- Null handling(3 columns:0~2)
Private Sub prc_XML_Null_Handling(ByVal R As Integer)
If (IsDBNull(frm_Main.dgv_Family(0, R).Value)) Then
Me.Col_0 = ""
Else
Me.Col_0 = frm_Main.dgv_Family(0, R).Value.ToString
End If
' ---
If (IsDBNull(frm_Main.dgv_Family(1, R).Value)) Then
Me.Col_1 = ""
Else
Me.Col_1 = frm_Main.dgv_Family(1, R).Value.ToString
End If
' ---
If (IsDBNull(frm_Main.dgv_Family(2, R).Value)) Then
Me.Col_2 = ""
Else
Me.Col_2 = frm_Main.dgv_Family(2, R).Value.ToString
End If
End Sub
' --- Create XML nodes (argument: column 0, 1, 2, and XmlTextWriter)
Private Sub sub_CreateNode _
(ByVal col_0 As String, ByVal col_1 As String, ByVal col_2 As String,
ByVal writer As XmlTextWriter)
' --- XML node start: output only columns 0-2
With frm_Main.dgv_Family
' -- 0: f_name
xmlWtr.WriteStartElement(.Columns(0).Name)
xmlWtr.WriteString(col_0)
xmlWtr.WriteEndElement()
' -- 1: l_name
xmlWtr.WriteStartElement(.Columns(1).Name)
xmlWtr.WriteString(col_1)
xmlWtr.WriteEndElement()
' -- 2: tel
xmlWtr.WriteStartElement(.Columns(2).Name)
xmlWtr.WriteString(col_2)
xmlWtr.WriteEndElement()
End With
End Sub
#End Region
End Class
-------------------------------------------------------------------
要するに・・・XML ファイルの3列(ゼロ~2)を
XmlTextReader で読み込み、
XmlTextWriter で書き込む・・・そんな処理です。
XML ファイルは実行ファイルと同じフォルダーに置いています。
最後までお読みいただき、ありがとうございます。
このサンプルプロジェクトを OneDrive に置いています。
お礼代わりにこれをシェアいたします。
ソースコード付きなので適宜修正してご利用ください。
ここをクリックすれば 99 XML_ImportExport.zip がダウンロードできます。
# 2019-06-26 追記
OneDrive で共有していたものを削除していたようです。
共有要望をいただいたので、再度アップロード・共有しました。
なお、コードのキレイさ(汚さ)は笑って無視してください。
前述のとおり、MSDN での問い合わせに対応するため
急いで既存処理を寄せ集めただけですから・・・
また、コードをそのままブログに貼り付けるとインデントが無くなり
全ての行頭が左端に寄ってしまいました。
なので、各行の先頭(空白部)は全角スペースで埋めています。
ご承知おきください。
---------------------------------------------------------
ブログ記事についてのお問い合わせは「質疑応答 掲示板」で・・・
# ご質問にはできる限りお答えしています。
ただし、お名前(本名)を書いていただいた場合に限らせていただきます。
ここをクリックして、北窓舎のサイトにもお立ち寄りください・・・
言語は VB.NET です。
画面(WindowsForm)に表示するために、DataGridView を使っています。
XML ファイルを読み込み、DataGridView に表示し、それを XML ファイルに書き出しています。
DataGridView は先頭列でソートしできるので、書き出した結果が元と違っているのが分かります。
なお、このサンプルは MSDN フォーラムでの問い合わせ対応用に作ったものです。
元の XML ファイル(Family.xml)を Excel で開くと次のように見えます。
テキストエディターで開くと、こんな感じ・・・
1列目がファーストネーム、2列目がラストネーム、3列目が電話番号です。
サンプルを実行するとこのようになります。
1.XML ファイルをインポートし DataGridView に格納
2.ファーストネームでソート
3.それを XML ファイルにエクスポート
さて、画面とコードは次のとおりです。
メインフォームの画像:
メインフォームのコード:
-------------------------------------------------------------------
Public Class frm_Main
#Region "=== Form: Load, Closing"
Private Sub frm_Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call cls_DGV.prc_Prepare_dgv_Family()
End Sub
#End Region
#Region "=== [Button]"
--[Import] buttn: Read XML and store data to DGV
Private Sub btn_OpenFile_Click(sender As Object, e As EventArgs) Handles btn_Import.Click
With Me.OpenFileDialog1
.InitialDirectory = System.Reflection.Assembly.GetExecutingAssembly().Location
.Title = "Select an XML file"
.Filter = "XML file (*.xml)|*.xml"
End With
If (Me.OpenFileDialog1.ShowDialog = DialogResult.OK) Then
Me.txt_InputFileName.Text = Me.OpenFileDialog1.FileName
Call Me.prc_Create_OutputFileName(Me.OpenFileDialog1.FileName)
Call cls_DGV.prc_Clear_dgv_Family()
Call cls_FileIO.prc_Read_File()
Me.dgv_Family.ClearSelection()
End If
End Sub
' --- decide output file name: addding "_Sorted" to original name
Private Sub prc_Create_OutputFileName(ByVal inputFileName As String)
' --- decide file name WithOut Path
Dim fileNameWOPath As String = System.IO.Path.GetFileName(inputFileName)
Dim extension As String = System.IO.Path.GetExtension(inputFileName)
fileNameWOPath = fileNameWOPath.Replace(extension, "_Sorted.xml")
' --- decide file name with Path
Dim dirName As String = System.IO.Path.GetDirectoryName(inputFileName)
Me.txt_OutputFileName.Text = dirName & "\" & fileNameWOPath
End Sub
' ---[Sort] button
Private Sub btn_Sort_Click(sender As Object, e As EventArgs) Handles btn_Sort.Click
' --- sort columns(0): f_name -- ascending
Me.dgv_Family.Sort(dgv_Family.Columns(0), System.ComponentModel.ListSortDirection.Ascending)
Me.dgv_Family.ClearSelection()
End Sub
' ---[Export] button: Write XML using DGV data
Private Sub btn_Export_Click(sender As Object, e As EventArgs) Handles btn_Export.Click
Call cls_FileIO.prc_Write_File()
If (MessageBox.Show _
("Export completed." & Chr(13) & "Open the exported file?", "Open?", MessageBoxButtons.YesNo) _
= DialogResult.Yes) Then
Dim p As System.Diagnostics.Process _
= System.Diagnostics.Process.Start(Me.txt_OutputFileName.Text)
End If
End Sub
#End Region
End Class
-------------------------------------------------------------------
cls_DGV のコード:
・・・メインフォーム上の DataGridView(dgv_Family)を定義する処理と
DataGridView をクリアする処理です。
-------------------------------------------------------------------
Public Class cls_DGV
Inherits frm_Main
' --- Prepare dgv_Family
Public Sub prc_Prepare_dgv_Family()
With frm_Main.dgv_Family
.ColumnHeadersHeight = 30 ' -- 列見出しの高さ
.RowTemplate.Height = 30 ' -- 行の高さ
.RowHeadersVisible = False ' -- ● 左端のレコードセレクターは非表示
.MultiSelect = False ' -- 複数選択は不可
.AllowUserToAddRows = False ' -- 行の追加禁止(末尾の新規行を表示しない)
.AllowUserToResizeColumns = True ' -- 列幅変更を許可
.BackgroundColor = Color.WhiteSmoke ' -- 背景色
.AlternatingRowsDefaultCellStyle.BackColor = Color.WhiteSmoke ' -- 1行おきの色
.SelectionMode = DataGridViewSelectionMode.FullRowSelect ' -- 選択は行全体
' --- ヘッダーの背景色
.EnableHeadersVisualStyles = False ' -- これが必要
.ColumnHeadersDefaultCellStyle.BackColor = Color.Gainsboro
.RowHeadersDefaultCellStyle.BackColor = Color.Gainsboro
' --- 列幅(初期値として)
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
.Columns(0).FillWeight = 30 ' -- f_name
.Columns(1).FillWeight = 30 ' -- l_name
.Columns(2).FillWeight = 40 ' -- tel
' --- 文字位置(ヘッダーはすべて中央揃え)
For idx As Integer = 0 To .Columns.Count - 1
.Columns(idx).HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter
Next
End With
End Sub
' --- Clear dgv_Family: delete all rows
Public Sub prc_Clear_dgv_Family()
For r As Integer = 0 To frm_Main.dgv_Family.Rows.Count - 1
frm_Main.dgv_Family.Rows.RemoveAt(0)
Next
End Sub
End Class
-------------------------------------------------------------------
一番大事なファイル入出力のコード:
-------------------------------------------------------------------
Imports System.Xml ' -- XML
Public Class cls_FileIO
Inherits frm_Main
#Region "=== Variables"
private xmlWtr As System.Xml.XmlTextWriter
Private Col_0, Col_1, Col_2 As String
Private maxCol As Integer = 2 ' -- last column index to export
#End Region
#Region "=== Read XML"
' --- Import from XML
Public Sub prc_Read_File()
If (System.IO.File.Exists(frm_Main.txt_InputFileName.Text) = False) Then
MessageBox.Show("File does not exist." & Chr(13) & frm_Main.txt_InputFileName.Text)
Exit Sub ' --▶ 処理を抜ける
End If
' --- load XML file: XmlTextReader
Dim xmlRdr As New XmlTextReader(frm_Main.txt_InputFileName.Text)
Dim myRow As Integer = 0
' --- Read XML file
While xmlRdr.Read()
If (xmlRdr.NodeType = XmlNodeType.Element) Then
' frm_Main.dgv_Family.Rows.Add() ' --◀ add row in DGV
' ---
Select Case xmlRdr.Name
Case = "f_name"
frm_Main.dgv_Family.Rows.Add() ' --◀ add Row in DGV
frm_Main.dgv_Family(0, myRow).Value = xmlRdr.ReadString()
Case = "l_name"
frm_Main.dgv_Family(1, myRow).Value = xmlRdr.ReadString()
Case = "tel"
frm_Main.dgv_Family(2, myRow).Value = xmlRdr.ReadString()
myRow += 1 ' --◀ add Row index
End Select
End If
End While
' --- post process
xmlRdr.Close()
xmlRdr.Dispose()
End Sub
#End Region
#Region "=== Write XML"
' --- Export to XML
Public Sub prc_Write_File()
' --- create instance of XML Writer
xmlWtr = New XmlTextWriter(frm_Main.txt_OutputFileName.Text, System.Text.Encoding.UTF8)
' --- output XML definition
xmlWtr.WriteStartDocument(True)
xmlWtr.Formatting = Formatting.Indented
xmlWtr.Indentation = 4
xmlWtr.WriteStartElement("Hokusosha") ' -- Space is not permitted
' --- dgv_Family: Loop by Rows
Dim myRow As Integer
For myRow = 0 To frm_Main.dgv_Family.RowCount - 1
Call Me.prc_XML_Null_Handling(myRow) ' -- Null handling
xmlWtr.WriteStartElement("Line")
Call Me.sub_CreateNode _
(Col_0, Col_1, Col_2, xmlWtr) ' -- create node (columns 0-2)
xmlWtr.WriteEndElement()
Next
' --- post process
xmlWtr.WriteEndElement()
xmlWtr.WriteEndDocument()
xmlWtr.Flush() ' -- settle
xmlWtr.Close() ' -- close
xmlWtr.Dispose() ' -- release from memory
End Sub
' --- Null handling(3 columns:0~2)
Private Sub prc_XML_Null_Handling(ByVal R As Integer)
If (IsDBNull(frm_Main.dgv_Family(0, R).Value)) Then
Me.Col_0 = ""
Else
Me.Col_0 = frm_Main.dgv_Family(0, R).Value.ToString
End If
' ---
If (IsDBNull(frm_Main.dgv_Family(1, R).Value)) Then
Me.Col_1 = ""
Else
Me.Col_1 = frm_Main.dgv_Family(1, R).Value.ToString
End If
' ---
If (IsDBNull(frm_Main.dgv_Family(2, R).Value)) Then
Me.Col_2 = ""
Else
Me.Col_2 = frm_Main.dgv_Family(2, R).Value.ToString
End If
End Sub
' --- Create XML nodes (argument: column 0, 1, 2, and XmlTextWriter)
Private Sub sub_CreateNode _
(ByVal col_0 As String, ByVal col_1 As String, ByVal col_2 As String,
ByVal writer As XmlTextWriter)
' --- XML node start: output only columns 0-2
With frm_Main.dgv_Family
' -- 0: f_name
xmlWtr.WriteStartElement(.Columns(0).Name)
xmlWtr.WriteString(col_0)
xmlWtr.WriteEndElement()
' -- 1: l_name
xmlWtr.WriteStartElement(.Columns(1).Name)
xmlWtr.WriteString(col_1)
xmlWtr.WriteEndElement()
' -- 2: tel
xmlWtr.WriteStartElement(.Columns(2).Name)
xmlWtr.WriteString(col_2)
xmlWtr.WriteEndElement()
End With
End Sub
#End Region
End Class
-------------------------------------------------------------------
要するに・・・XML ファイルの3列(ゼロ~2)を
XmlTextReader で読み込み、
XmlTextWriter で書き込む・・・そんな処理です。
XML ファイルは実行ファイルと同じフォルダーに置いています。
最後までお読みいただき、ありがとうございます。
このサンプルプロジェクトを OneDrive に置いています。
お礼代わりにこれをシェアいたします。
ソースコード付きなので適宜修正してご利用ください。
ここをクリックすれば 99 XML_ImportExport.zip がダウンロードできます。
# 2019-06-26 追記
OneDrive で共有していたものを削除していたようです。
共有要望をいただいたので、再度アップロード・共有しました。
なお、コードのキレイさ(汚さ)は笑って無視してください。
前述のとおり、MSDN での問い合わせに対応するため
急いで既存処理を寄せ集めただけですから・・・
また、コードをそのままブログに貼り付けるとインデントが無くなり
全ての行頭が左端に寄ってしまいました。
なので、各行の先頭(空白部)は全角スペースで埋めています。
ご承知おきください。
---------------------------------------------------------
ブログ記事についてのお問い合わせは「質疑応答 掲示板」で・・・
# ご質問にはできる限りお答えしています。
ただし、お名前(本名)を書いていただいた場合に限らせていただきます。
ここをクリックして、北窓舎のサイトにもお立ち寄りください・・・
今、再度 OneDrive にアップロードして共有しました(ダウンロード可能にしました)。
ご確認ください。