티스토리 뷰

C#/C# 강좌 Winform

Doridori C# 강의) 17. XMLReader, XMLWriter

꼬꼬마도리도리 2018. 9. 16. 21:27

======================================================

안녕하세요 Doridori 입니다. 


지난번에 작성 했던 텍스트 파일을 읽어오는 StreamReader, StreamWriter에서 한단계 발전 시킨 형태로 XML에 대한 내용으로 XmlReader, XmlWriter에 대해 준비해 보았습니다. 


이번강의의 경우 xml뿐 아니라 static, using, Dictionary에 대해서도 간략하게 진행 하니 한번 정도 들어봅시면 좋을 것 같습니다. 


뭔가 열심히 준비하는데 봐주시는 분들이 거의 없어서 아쉽긴 하지만 기왕 시작한거 저의 페이스 대로 마무리 까지 열심히 진행 해보도록 하겠습니다.

======================================================


XmlReader, XmlWriter


Source UI) (지난강의 UI를 그대로 사용 하였습니다.)

Soruce 전체) Study_17_XMLReader_XMLWriter.zip

교재) 17강 XMLReader, XMLWriter.pdf


지난 강의에 설명드렸지만 보통 프로그램을 하다보면 텍스트 -> XML -> DB 순서로 Data를 저장하게 됩니다. 

(제가 그렇습니다.~! =0=;; 처음부터 DB를 잘 쓰게 배우셨다면 필요 없을 수도 있지만 이런저런식으로 다 사용 할 수도 있으니 알아두면 좋습니다.)


Stream의 경우 Log형태로 많이 사용 되지만 XML의 형태는 프로그램을 시작할때의 설정 값을 저장 하는 용도로 많이 사용 됩니다.

지난번에는 UI에 바로 작성 하였지만 이번에는 나중에 가져다 쓰시기 편하도록 XML에 대한 내용만 별도의 Class로 분리 하였습니다. 

(UI와 코드 부분을 분리 하는 방식으로 작성 할 경우 나중에 프로그램 수정이 편해 집니다.)


UI)

UI의 경우 지난강의에 썻던 부분을 그대로 사용 하였습니다. .(코드도 지난 강의 마지막 부터 이어서 사용 했습니다.)

지난강의의 연장선이라고 보시면 될듯 합니다. ^^;;


강의)


Source)

CXMLControl)

Xml을 읽어 오는 부분과 Xml File을 저장 하는 부분을 별도의 Class로 작성 하여 사용 하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
 
namespace _17_XMLControl
{
    class CXMLControl
    {
        // Dictionary 및 XML의 항목을 정의 ( static(정적) 변수로 사용 : 프로그램 실행 시 메모리에 바로 할당
        public static string _TEXT_DATA = "TEXT_DATA";
        public static string _CBOX_DATA = "CBOX_DATA";
        public static string _NUMBER_DATA = "NUMBER_DATA";
 
 
        /// <summary>
        /// XML을 저장 하기 위해 사용
        /// </summary>
        /// <param name="strXMLPath">저장 할 XML File의 경로 및 파일명</param>
        /// <param name="DXMLConfig">XML로 저장 할 항목</param>
        public void fXML_Writer(string strXMLPath, Dictionary<string,string> DXMLConfig)
        {
            // using 범위 내에 XmlWriter를 정의 하여 using을 벗어 나게 될 경우 자동으로 Dispose 하여 메모리를 관리
            using (XmlWriter wr = XmlWriter.Create(strXMLPath))
            {
                // XML 형태의 Data를 작성 (결과 및 예제 확인)
 
                wr.WriteStartDocument();
 
                // Setting#01
                wr.WriteStartElement("SETTING");
                wr.WriteAttributeString("ID""0001");  // attribute 쓰기
 
                wr.WriteElementString(_TEXT_DATA, DXMLConfig[_TEXT_DATA]);
                wr.WriteElementString(_CBOX_DATA, DXMLConfig[_CBOX_DATA]);
                wr.WriteElementString(_NUMBER_DATA, DXMLConfig[_NUMBER_DATA]);
 
                wr.WriteEndElement();
                wr.WriteEndDocument();
            }
        }
 
 
        /// <summary>
        /// XML을 읽어 오기 위해 사용
        /// </summary>
        /// <param name="strXMLPath">읽어 올 XML File의 경로 및 파일명</param>
        /// <returns></returns>
        public Dictionary<stringstring> fXML_Reader(string strXMLPath)
        {
            Dictionary<stringstring> DXMLConfig = new Dictionary<stringstring>();  // 읽어 온 XML Data를 Dictionary에 저장하기 위해 선언 및 초기화
 
            // using 범위 내에 XmlReader를 정의 하여 using을 벗어 나게 될 경우 자동으로 Dispose 하여 메모리를 관리
            using (XmlReader rd = XmlReader.Create(strXMLPath))
            {
                // xml을 한줄 씩 읽으면서 필요 한 정보를 가져 옴
                while (rd.Read())
                {
                    if (rd.IsStartElement())
                    {
                        if (rd.Name.Equals("SETTING"))
                        {
                            string strID = rd["ID"];  // attribute 읽기   //여기 뭐지??  ID를 읽고 뭐하는거지??
                            rd.Read();  //다음 노드로 이동
 
                            string strTEXT = rd.ReadElementContentAsString(_TEXT_DATA, "");  // 키 값을 기준으로 결과 값을 가져 옴
                            DXMLConfig.Add(_TEXT_DATA, strTEXT);   // 키값과 가져온 결과 값을 Dictionary에 저장
 
                            string strCBOX = rd.ReadElementContentAsString(_CBOX_DATA, "");
                            DXMLConfig.Add(_CBOX_DATA, strCBOX);
 
                            string strNUMBER = rd.ReadElementContentAsString(_NUMBER_DATA, "");
                            DXMLConfig.Add(_NUMBER_DATA, strNUMBER);
                        }
                    }
                }
            }
 
            return DXMLConfig;   // 작성 한 Dictionary를 반환
        }
    }
}
 
cs


UI)

UI에서 기존에 작성 했던 CXMLControl을 호출해서 사용함으로써 UI의 Code를 간단하게 만들었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace _17_XMLControl
{
    public partial class Form1 : Form
    {
 
        CXMLControl _xml = new CXMLControl();   // 만들어 놓은 CXMLControl을 사용하기 위해 선언 및 초기화 (기본 생성자)
        Dictionary<stringstring> _dData = new Dictionary<stringstring>();  // CXMLControl과 Data를 주고 받기 위해 Dictionary를 선언 및 초기화
 
        /// <summary>
        /// 진입점
        /// </summary>
        public Form1()
        {
            InitializeComponent();
        }
 
 
        /// <summary>
        /// GroupBox 안에 있는 Data를 화면에 보여주기 위한 상단 TextBox로 보냄
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfigSet_Click(object sender, EventArgs e)
        {
            string strEnter = "\r\n";
 
            string strText = tboxData.Text;
            bool bChecked = cboxData.Checked;
            int iNumber = (int)numData.Value;
 
            StringBuilder sb = new StringBuilder();
 
 
            _dData.Clear();  // 기존에 Dictionary에 Data가 남아 있을 수 있으므로 작성 하기 전 초기화 시킴
 
            // Dictionary에 UI에서 작성 한 항목과 값을 Key와 Value로 저장
            _dData.Add(CXMLControl._TEXT_DATA, strText);
            _dData.Add(CXMLControl._CBOX_DATA, bChecked.ToString());
            _dData.Add(CXMLControl._NUMBER_DATA, iNumber.ToString());
 
 
            sb.Append(strText + strEnter);
            sb.Append(bChecked.ToString() + strEnter);
            sb.Append(iNumber.ToString() + strEnter);
 
            tboxConfigData.Text = sb.ToString();
        }
 
 
        /// <summary>
        /// Main TextBox에 있는 문자를 텍스트 파일로 저장
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            string strFilePath = string.Empty;
 
            SFDialog.InitialDirectory = Application.StartupPath;   //프로그램 실행 파일 위치
            SFDialog.FileName = "*.xml";
            SFDialog.Filter = "xml files (*.xml)|*.txt|All files (*.*)|*.*";
 
            if (SFDialog.ShowDialog() == DialogResult.OK)
            {
                strFilePath = SFDialog.FileName;
 
                //// StreamWriter를 이용해서 텍스트 파일을 일어노는 부분을 구현
                //StreamWriter swSFDialog = new StreamWriter(strFilePath);
 
                //swSFDialog.WriteLine(tboxConfigData.Text);
                //swSFDialog.Close();
 
                //File.WriteAllText(strFilePath, tboxConfigData.Text);
 
                _xml.fXML_Writer(strFilePath, _dData);   // 작성 한 CXMLControl에서 fXML_Writer를 호출해서 XML File을 생성
            }
 
        }
 
 
        /// <summary>
        /// 텍스트 파일을 읽어와서 Main TextBox에 보여 줌
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLoad_Click(object sender, EventArgs e)
        {
            string strFilePath = string.Empty;
 
            OFDialog.InitialDirectory = Application.StartupPath;   //프로그램 실행 파일 위치
            OFDialog.FileName = "*.xml";
            OFDialog.Filter = "xml files (*.xml)|*.*";
 
            StringBuilder sb = new StringBuilder();
 
            if (OFDialog.ShowDialog() == DialogResult.OK)
            {
                strFilePath = OFDialog.FileName;
                
                //// StreamReader를 이용해서 텍스트 파일을 일어노는 부분을 구현
                //StreamReader srOFDialog = new StreamReader(strFilePath, Encoding.UTF8, true);
 
                //while (srOFDialog.EndOfStream == false)
                //{
                //    sb.Append(srOFDialog.ReadLine());
                //    sb.Append("\r\n");
                //}
 
                sb.Append(File.ReadAllText(strFilePath));  // 텍스트 파일을 String 형태로 한번에 읽어 옴
 
                //string[] dd =  File.ReadAllLines(strFilePath);   // 텍스트 파일을 한줄 씩 String 배열 형태로 한번에 읽어 옴
 
 
                tboxConfigData.Text = sb.ToString();
 
                _dData.Clear();   // 기존에 Dictionary에 Data가 남아 있을 수 있으므로 작성 하기 전 초기화 시킴
                _dData = _xml.fXML_Reader(strFilePath);   // 작성 한 CXMLControl에서 fXML_Reader를 호출해서 XML File을 읽어서 필요한 정보를 Dictionary 형태로 가져 옴
            }
        }
 
 
        /// <summary>
        /// Config Data를 Group Box안에 있는 Control들에 Set
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfigRead_Click(object sender, EventArgs e)
        {
            //string[] strConfig = tboxConfigData.Text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);  // 문자열 안에있는 '\r\n'을 기준으로 split 시킴
 
            //tboxData.Text = strConfig[0];
            //cboxData.Checked = bool.Parse(strConfig[1]);
            //numData.Value = int.Parse(strConfig[2]);
 
 
            // Dictionary에 있는 정보를 UI에 입력함
            tboxData.Text = _dData[CXMLControl._TEXT_DATA];
            cboxData.Checked = bool.Parse(_dData[CXMLControl._CBOX_DATA]);
            numData.Value = int.Parse(_dData[CXMLControl._NUMBER_DATA]);
        }
    }
}
 
cs



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함