none
[C#] Xml파일과 Combo박스 리스트 연동 RRS feed

  • 질문

  • C#으로 Xml 데이터 분석 프로그램을 만들고 있습니다.

    좀 질문이 많은데요.... 회사에서 쉬운 업무를 위해 프로그램 하나를 만들고 있는데...

    C#은 잘 모르겠네요 ㅋ;;

    1. 콤보박스와 Xml파일 연동

    툴바의 파일열기 아이콘을 통하여 xml 파일을 불러오면

    콤보박스 리스트에는 xml내 name의 value값에 내가 원하는 문자가 포함되어 있는 것의 name값들만 리스트로 나타내고 싶습니다.

    예를 들어, 다음과 같은 xml 문서에서

    <Source>
     <Item id="22791" subscriptionid="0" name="other_data_1" mapping="direct" encoding="dec" index="0">3,3,3</NvItem>
     <Item id="22949" subscriptionid="0" name="data_Multi_1" mapping="direct" encoding="dec" index="0">4,5,6,7</NvItem>
     <Item id="22950" subscriptionid="0" name="data_Multi_2" mapping="direct" encoding="dec" index="0">9,7,11,13,15</NvItem>
     <Item id="22954" subscriptionid="0" name="data_Multi_3" mapping="direct" encoding="dec" index="0">6,8,9,70,13</NvItem>
     <Item id="22972" subscriptionid="0" name="data_Mutli_4" mapping="direct" encoding="dec" index="0">3,6,9,15,49</NvItem>
     <Item id="22982" subscriptionid="0" name="UNKNOWN" mapping="direct" encoding="dec" index="0">0,0,0,0,0,0</NvItem>
     <Item id="23245" subscriptionid="0" name="other_data_2" mapping="direct" encoding="dec" index="0">3,6,9,11,15</NvItem>
     <Item id="23247" subscriptionid="0" name="other_data_3" mapping="direct" encoding="dec" index="0">3,7,9,15</NvItem>
    </Source>  

    name의 value값에 Multi가 들어간 것들만 콤보박스 리스트에 나타내고 싶습니다.

    파일 열기를 통하여 xml 파일을 불러오고 콤보박스의 화살표를 누르면

    data_Multi_1

    data_Multi_2

    data_Multi_3

    data_Multi_4

    이렇게 4개의 리스트만 나타나겠죠?

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Xml;
    using System.Xml.Schema;
    namespace MLD_manager
    {
        public partial class MLD_manager : Form
        {
            OpenFileDialog ofd = new OpenFileDialog();
            SaveFileDialog sfd = new SaveFileDialog();
            public MLD_manager()
            {
                InitializeComponent();
            }
            private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
            {
            }
            private void toolStripButton1_Click(object sender, EventArgs e)//임시
            {
                ofd.Filter = "Xml 파일(*.xml)|*.xml|모든파일(*.*)|*.*"; //원하는 확장자
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    StreamReader re = new StreamReader(ofd.FileName);
                    textBox1.Text = string.Format("File Path - <{0}>", ofd.FileName);//파일 경로 출력
                    //textBox1.Text = re.ReadToEnd(); //파일 내용 출력
                    re.Close();
                }
            }
            private void toolStripButton2_Click(object sender, EventArgs e)//임시
            {
                sfd.Filter = "Xml 파일(*.xml)|*.xml|모든파일(*.*)|*.*";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    StreamWriter sw = new StreamWriter(sfd.FileName);
                    sw.Write(textBox1.Text);
                    sw.Close();
                }
            }
            private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
            {
                AboutBox1 ab = new AboutBox1();     //About 폼을 객체화
                ab.ShowDialog();
            }
            private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
            {
            }
            private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
            {
            }
            private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
            }
        }
    }

    현재 소스는 여기까지만 진행되어 있구요...

    우선 이것부터 해결하고 다음 질문을...올려야 할 것 같네요 ㅠㅠ

    위 기능을 구현하는데 필요한 코드와 어느 부분에 추가시켜야 하는지 자세히좀 부탁드릴게요 ^^;



    • 편집됨 Byeongha, Kim 2012년 11월 19일 월요일 오전 1:38
    2012년 11월 19일 월요일 오전 1:16

답변

  • 정성태 MVP님 말씀하신데로

    XmlDocument doc = new XmlDocument();

    doc.Load(FilePath);

    이런식으로 읽어서 루트부터 MoveNext하면서 읽어 내려가는 방법이 있습니다.

    또한 약간 구현해 놓으신 소스를 응용하면 초보자가 이해하기 쉬운 다음과 같은 방법이 있을 수 있겠습니다.

    동작은 (1)의 메뉴를 클릭해서 말씀하신 XML파일을 읽습니다.

    (2)의 텍스트 박스에 검색어를 입력합니다. (3)의 버튼을 누르면 콤보박스가 세팅이 됩니다.

    (4)의 콤보박스를 열어서 확인합니다.

    전체 소스는 다음과 같습니다.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    using System.IO;
    
    namespace WindowsFormsApplication2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
    
            private DataSet ds;
    
            private void toolStripButton1_Click(object sender, EventArgs e)
            {
                ofd.Filter = "Xml 파일(*.xml)|*.xml|모든파일(*.*)|*.*"; //원하는 확장자
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    StreamReader re = new StreamReader(ofd.FileName);
                    //textBox1.Text = string.Format("File Path - <{0}>", ofd.FileName);//파일 경로 출력
                    //textBox1.Text = re.ReadToEnd(); //파일 내용 출력
    
                    ds = new DataSet();
                    ds.ReadXml(re);
    
                    re.Close();
    
                    
                }
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                {
                    DataRow[] arDR = ds.Tables[0].Select("name like '%" + textBox1.Text.Trim() + "%'");
                    if (arDR.Length > 0)
                    {
                        DataTable dt = new DataTable();
                        dt.Columns.Add("Text", typeof(string));
                        dt.Columns.Add("Value", typeof(string));
    
                        DataRow dr;
                        for (int i = 0; i < arDR.Length; i++)
                        {
                            dr = dt.NewRow();
                            dr["Value"] = arDR[i]["Id"];
                            dr["Text"] = arDR[i]["name"];
                            dt.Rows.Add(dr);
                        }
    
                        comboBox1.DisplayMember = "Text";
                        comboBox1.ValueMember = "Value";
                        comboBox1.DataSource = dt;
                    }
                }
    
            }
        }
    }

    우선 제시해주신 XML파일 내용중에 닫는 태그 부분이 </Item>으로 수정되어야 제대로 작동이 될것 같습니다. 그리고 Multi_4는 철자가 틀려서 결과에 나오지 않는 것입니다.

    그럼...

    • 편집됨 GoldrushKoreaMVP 2012년 11월 19일 월요일 오전 10:50
    • 답변으로 제안됨 Sungman KOMVP 2012년 11월 20일 화요일 오전 12:21
    • 답변으로 표시됨 Byeongha, Kim 2012년 11월 22일 목요일 오전 5:25
    2012년 11월 19일 월요일 오전 10:46

모든 응답

  • 우선, XmlDocument 로 XML 파일을 읽어들이고 XPath 구문을 이용해서 name 속성에 "Multi" 가 들어간 것만 선택해 내면 XmlNodeList를 얻을 수 있습니다. 그걸 열거하면서 Combo랑 연결시키면 되겠지요.

    XPath를 잘 모르신다면, 그냥 자식 노드 모드 열람하면서 수작업으로 name 속성의 값을 살펴보면 됩니다.

    시작은 XmlDocument 부터 알아보고, 관련 예제를 하나씩 살펴보시면 어떻게 구현해야 할 지 눈에 들어올 것입니다.

    2012년 11월 19일 월요일 오전 10:01
  • 정성태 MVP님 말씀하신데로

    XmlDocument doc = new XmlDocument();

    doc.Load(FilePath);

    이런식으로 읽어서 루트부터 MoveNext하면서 읽어 내려가는 방법이 있습니다.

    또한 약간 구현해 놓으신 소스를 응용하면 초보자가 이해하기 쉬운 다음과 같은 방법이 있을 수 있겠습니다.

    동작은 (1)의 메뉴를 클릭해서 말씀하신 XML파일을 읽습니다.

    (2)의 텍스트 박스에 검색어를 입력합니다. (3)의 버튼을 누르면 콤보박스가 세팅이 됩니다.

    (4)의 콤보박스를 열어서 확인합니다.

    전체 소스는 다음과 같습니다.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    using System.IO;
    
    namespace WindowsFormsApplication2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
    
            private DataSet ds;
    
            private void toolStripButton1_Click(object sender, EventArgs e)
            {
                ofd.Filter = "Xml 파일(*.xml)|*.xml|모든파일(*.*)|*.*"; //원하는 확장자
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    StreamReader re = new StreamReader(ofd.FileName);
                    //textBox1.Text = string.Format("File Path - <{0}>", ofd.FileName);//파일 경로 출력
                    //textBox1.Text = re.ReadToEnd(); //파일 내용 출력
    
                    ds = new DataSet();
                    ds.ReadXml(re);
    
                    re.Close();
    
                    
                }
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0] != null && ds.Tables[0].Rows.Count > 0)
                {
                    DataRow[] arDR = ds.Tables[0].Select("name like '%" + textBox1.Text.Trim() + "%'");
                    if (arDR.Length > 0)
                    {
                        DataTable dt = new DataTable();
                        dt.Columns.Add("Text", typeof(string));
                        dt.Columns.Add("Value", typeof(string));
    
                        DataRow dr;
                        for (int i = 0; i < arDR.Length; i++)
                        {
                            dr = dt.NewRow();
                            dr["Value"] = arDR[i]["Id"];
                            dr["Text"] = arDR[i]["name"];
                            dt.Rows.Add(dr);
                        }
    
                        comboBox1.DisplayMember = "Text";
                        comboBox1.ValueMember = "Value";
                        comboBox1.DataSource = dt;
                    }
                }
    
            }
        }
    }

    우선 제시해주신 XML파일 내용중에 닫는 태그 부분이 </Item>으로 수정되어야 제대로 작동이 될것 같습니다. 그리고 Multi_4는 철자가 틀려서 결과에 나오지 않는 것입니다.

    그럼...

    • 편집됨 GoldrushKoreaMVP 2012년 11월 19일 월요일 오전 10:50
    • 답변으로 제안됨 Sungman KOMVP 2012년 11월 20일 화요일 오전 12:21
    • 답변으로 표시됨 Byeongha, Kim 2012년 11월 22일 목요일 오전 5:25
    2012년 11월 19일 월요일 오전 10:46
  • 좋은정보 감사합니다 ^^

    2012년 11월 19일 월요일 오전 10:55
  • 자세히 잘 설명해 주셨네요 ㅠㅠ

    너무 감사드립니다

    2012년 11월 19일 월요일 오전 10:55