[.Net] XML ํ์ผ ์ฝ๊ธฐ์ ์ฐ๊ธฐ, ๊ทธ๋ฆฌ๊ณ ์ง๋ ฌํ(Serialization)๋ก ๊ฐ์ฒด์ ์ฐ๋ํ๋ ๋ฐฉ๋ฒ(์์ ํฌํจ)
XML์ด๋?
XML์ eXtensible Markup Language์ฝ์๋ก, ๋ง ๊ทธ๋๋ก 'ํ์ฅ ๊ฐ๋ฅํ ๋งํฌ์ ์ธ์ด'๋ฅผ ๋ปํ๋๋ฐ, ์ข ๋ ์๋ฏธ๋ฅผ ํ์๋ฉด '๋ฐ์ดํฐ๋ฅผ ์ ์ํ๋ ๊ท์น์ ์ ๊ณตํ๋ ๋งํฌ์ ์ธ์ด'์ ๋๋ค.
XML์ ๋ชฐ๋์ ๋์๋ ํ๋ก๊ทธ๋จ์ ์ค์ ํ์ผ๋ก INI ํฌ๋งท์ ์ฌ์ฉํ์์ผ๋, XML์ ์ ํ ์ดํ๋ก๋ ์ค๊ณง XML ํ์ผ๋ง ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ๋ฐฐ์ด ํํ๋ก ๋์ด์ด ๊ฐ๋ฅํ๊ณ , ๋ฐ์ดํฐ์ ๊น์ด๋ ์์ ๋กญ๊ฒ ์ค์ ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ํ, ๊ฐ์ฅ ์ค์ํ ์ ์ ์ง๋ ฌํ(Serialization)๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด์ ์ฐ๋์ด ์ฌ์ ์ฝ๊ณ ์ฐ๊ธฐ๊ฐ ์์ฃผ ํธ๋ฆฌํ๋ค๋ ์ ์ ๋๋ค.
๊ทธ๋ผ, ๋ณธ๋ฌธ์์๋ XML ํ์ผ์ ๊ตฌ์กฐ์ C#์ผ๋ก ์ด๋ป๊ฒ ์ฝ๊ณ ์ฐ๋์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , Serialization์ ์ฌ์ฉํด ์ด๋ป๊ฒ ๊ฐ์ฒดํํ๋์ง ์ค๋ช ํ๊ฒ ์ต๋๋ค.
XML ๊ตฌ์กฐ
XML์ ํธ๋ฆฌ(Tree)
๊ตฌ์กฐ์
๋๋ค. ํ๋์ ๋
ธ๋(Node)
๋ฅผ ์์(Element)
๋ผ๊ณ ๋ถ๋ฅด๊ณ , ๋ฃจํธ(Root)
๋ถํฐ ์์ํ์ฌ ํ์์์๊ฐ ์ด์ด์ง๋๋ค. ํ์ ์์ ์
์ฅ์์ ์์ ์์๋ฅผ ๋ถ๋ชจ(Parent)
์์๋ผ๊ณ ๋ถ๋ฅด๊ณ , ๋ฐ๋๋ก๋ ์์(Child)
์์๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ ์์๋ ์์ฑ(Attribute)
์ ๊ฐ์ง ์ ์์ต๋๋ค. ์๋ ์ด๋ฏธ์ง๋ Product ๋
ธ๋ ์ด๋ฆ์ 'index'๋ผ๋ ์์ฑ๊ณผ '0'์ด๋ผ๋ ๊ฐ์ด ํฌํจ๋ ๋ชจ์ต์
๋๋ค.
๊ทธ๋ผ ๊ฐ๋จํ๊ฒ ๋ฐ ๋ณ๋ก ํ์๋ค์ ๊ฐ์ธ ์ ๋ณด๊ฐ ๋ด๊ธด XML์ ์์๋ก ๋ณด๊ฒ ์ต๋๋ค. A์ B๋ผ๋ ์ด๋ฆ์ Class๊ฐ ์๊ณ , Class ๋ณ๋ก ๋ช ๋ช ์ ํ์์ด ํฌํจ๋์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ ํ์์ ์ ๋ณด์๋ ์ด๋ฆ๊ณผ ํธ๋ํฐ ๋ฒํธ๊ฐ ๋ด๊ฒจ ์์ต๋๋ค.
<?xml version="1.0"?>
<Root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Class Name="A">
<Student Index="0">
<Name>์ฒ ์</Name>
<Phone>010-xxxx-xxxx</Phone>
</Student>
<Student Index="1">
<Name>์ํฌ</Name>
<Phone>010-yyyy-yyyy</Phone>
</Student>
</Class>
<Class Name="B">
<Student Index="0">
<Name>์งฑ๊ตฌ</Name>
<Phone>010-zzzz-zzzz</Phone>
</Student>
<Student Index="1">
<Name>๋งน๊ตฌ</Name>
<Phone>010-xxxx-yyyy</Phone>
</Student>
<Student Index="2">
<Name>๊ธฐ์</Name>
<Phone>010-xxxx-zzzz</Phone>
</Student>
</Class>
</Root>
์ฌ์ค ๊ตณ์ด 'Index' ์์ฑ์ ๋ถ์ผ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ Name๊ณผ Phone ๋ ธ๋๋ ์์ฑ์ผ๋ก ๋ฃ์ผ๋ฉด ๋์ฑ ์ฌํํด์ง์ฃ . ๊ทธ๋ผ ์ ํ์ผ์ ์ฝ๋๋ก ์ด๋ป๊ฒ ๋ถ๋ฌ์ฌ ์ ์๋์ง, ์ด๋ป๊ฒ ๋ ธ๋์ ๊ฐ์ ์ ๊ทผํ๋์ง ๋ณด๊ฒ ์ต๋๋ค.
using System.Xml;
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK )
{
XmlDocument doc = new XmlDocument();
doc.Load(dlg.FileName);
XmlNodeList nodes = doc.SelectNodes(@"/Root/Class");
var classes = nodes.Count; //๋ฐํ ๊ฐ: 2
nodes = doc.SelectNodes(@"/Root/Class[@Name='B']/Student");
var students = nodes.Count; //๋ฐํ ๊ฐ: 3
var node = doc.SelectSingleNode(@"/Root/Class[@Name='B']/Student[@Index='1']/Name");
var name = node.InnerText; //๋ฐํ ๊ฐ: ๋งน๊ตฌ
}
}
catch(Exception exc)
{
MessageBox.Show(exc.Message);
}
}
๋
ธ๋์ ์ ๊ทผํ๊ธฐ ์ํด์๋ ์ฌ๋ฐ๋ฅธ XPath(XML Path) ์
์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ ์์์ฒ๋ผ, ์ ๋ ๊ฒฝ๋ก ๋๋ ์๋ ๊ฒฝ๋ก๋ฅผ ์
๋ ฅํด์ผ ํ๋ฉฐ, ์์ฑ์ ์ ๊ทผํ๊ธฐ ์ํด์๋ ๋
ธ๋์ [@์์ฑ='๊ฐ']
ํค์๋๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
๋ง์ฝ, ๋ถ๋ฌ์ค๋ ๊ฒ๋ฟ๋ง ์๋๋ผ ๋
ธ๋ ์ฝ์
, ์ญ์ , ๊ฐ ๋ณ๊ฒฝ ๋ฑ์ ํธ์ง๋ ์ํ๋ค๋ฉด CreateElement
, RemoveChild
, AppendChild
, CreateAttribute
๋ฑ์ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
XMLDocument์ ์์ธํ ์ฌ์ฉ๋ฒ์ ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์ธ์.
https://learn.microsoft.com/ko-kr/dotnet/api/system.xml.xmldocument?view=netframework-4.8
ํ๋ก๊ทธ๋จ ์ด์ ์ค XML์ ํธ์งํ๊ธธ ์ํ๋ค๋ฉด ์ฌ์ฉํ๊ธฐ ์ฝ๊ฒ Wrapper Class๋ฅผ ๋ง๋๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค.
XML ์ง๋ ฌํ
์ง๋ ฌํ(Serialize)
๋, ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ์ด๋ ์ ์ก์ ์ํด ์ฐ์์ ์ธ ๋ฐ์ดํธ ๋จ์์ ๋ฐ์ดํฐ๋ก ๊ฐ๊ณตํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ด๋ ๊ฒ ์ง๋ ฌํ๋ ๋ฐ์ดํฐ๋ ๋ฐ๋๋ก ์ญ์ง๋ ฌํ(Deserialize)
๋ฅผ ํตํด ๋ค์ ์๋์ ๋ฐ์ดํฐ๋ก ๋๋๋ฆด ์ ์์ต๋๋ค. XML ์ง๋ ฌํ๋ ์ด๋ค ๊ฐ์ฒด๋ฅผ XML ๋ฐ์ดํฐ๋ก ์ง๋ ฌํํ์ฌ ์ ์ฅ(๋๋ ์ ์ก)ํ๊ณ , ๋ค์ ์ง๋ ฌํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋๋๋ฆฌ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์์์ ์์๋ก ๋ณด์ฌ์คฌ๋ ํ์ ์ ๋ณด๊ฐ ๋ด๊ธด XML ๊ตฌ์กฐ๋ฅผ ๊ฐ์ฒด๋ก ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
using System.Xml.Serialization;
namespace ExamXML
{
[Serializable]
[XmlRoot("Root")]
public class School
{
[XmlElement("Class")]
public List<Class> Classes { get; set; }
}
[Serializable]
public class Class
{
[XmlAttribute("Name")]
public string Name { get; set; }
[XmlElement("Student")]
public List<Student> Students { get; set; }
}
[Serializable]
public class Student
{
[XmlAttribute("Index")]
public int Index { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Phone")]
public string Phone { get; set; }
}
}
Serializable
ํค์๋๋ ๊ฐ์ฒด๊ฐ ์ง๋ ฌํํ ์ ์๋ค๋ ์๋ฏธ์ด๊ณ , XmlRoot
์ XmlElement
๋ ๋
ธ๋์ ์ด๋ฆ, ๊ทธ๋ฆฌ๊ณ XmlAttrinute
๋ ์์ฑ์ ์๋ฏธํฉ๋๋ค.
๊ฐ์ฒด๋ฅผ XML ์ง๋ ฌํํ๊ธฐ
ํ์ ์ ๋ณด๊ฐ ๋ด๊ธด School ๊ฐ์ฒด๋ฅผ Xml ์ง๋ ฌํํ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
private void btnSeiralize_Click(object sender, EventArgs e)
{
try
{
var school = new School
{
Classes = new List<Class>
{
new Class
{
Name = "A",
Students = new List<Student>
{
new Student { Index = 0, Name = "์ฒ ์", Phone = "010-xxxx-xxxx" },
new Student { Index = 1, Name = "์ํฌ", Phone = "010-yyyy-yyyy" }
}
},
new Class
{
Name = "B",
Students = new List<Student>
{
new Student { Index = 0, Name = "์งฑ๊ตฌ", Phone = "010-zzzz-zzzz" },
new Student { Index = 1, Name = "๋งน๊ตฌ", Phone = "010-xxxx-yyyy" },
new Student { Index = 2, Name = "๊ธฐ์", Phone = "010-xxxx-zzzz" }
}
}
}
};
SaveFileDialog dlg = new SaveFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
XmlSerializer serializer = new XmlSerializer(typeof(School));
using (FileStream fileStream = new FileStream(dlg.FileName, FileMode.Create))
{
serializer.Serialize(fileStream, school);
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
๊ฐ์ฒด๋ฅผ XML ๊ตฌ์กฐ๋ก ์ง๋ ฌํํ ๊ฒ์ด๋, ํ์ฅ์๋ XML๋ก ์ง์ ํฉ๋๋ค. ์ ์ฅ๋ ํ์ผ์ ์ด์ด๋ณด๋ฉด ์ฒ์์ ์ ์ํ XML ํ์ผ๊ณผ ๋์ผํฉ๋๋ค.
XML ํ์ผ์ ๊ฐ์ฒด๋ก ์ญ์ง๋ ฌํํ๊ธฐ
์ด๋ฒ์ ๋ฐ๋๋ก, XML ํ์ผ์ ๋ถ๋ฌ์ค๋ฉด School ๊ฐ์ฒด๋ก ๋ณํ์ด ๊ฐ๋ฅํฉ๋๋ค.
private void btnDeserialize_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
XmlSerializer serializer = new XmlSerializer(typeof(School));
using (FileStream fileStream = new FileStream(dlg.FileName, FileMode.Open))
{
School school = (School)serializer.Deserialize(fileStream);
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
์ ์ฝ๋๋ฅผ ์ฌ์ฉํด XML ํ์ผ์ ๋ถ๋ฌ์ค๋ฉด, ์๋์ ๊ฐ์ด ๊ฐ์ฒด๋ฅผ ์ป์ ์ ์์ต๋๋ค.
์ ๋ฆฌํ๊ธฐ
๊ฐ์ธ์ ์ผ๋ก XML์ ์ฃผ๋ก ํ๋ก๊ทธ๋จ์ ์์คํ ์ค์ ๊ฐ์ ๊ด๋ฆฌํ๋ ์ฉ๋๋ก ์ฌ์ฉํฉ๋๋ค. INI๋ณด๋ค ์ฌ์ฉํ๊ธฐ ํธํ๊ณ ์ง๋ ฌํ๋ฅผ ํตํด ๊ฐ์ฒด ๊ด๋ฆฌ๊ฐ ๋ ์ฉ์ดํ ๊ฒ ๊ฐ์ต๋๋ค. ์ฐธ๊ณ ๋ก, ์ง๋ ฌํ๋ XML๋ง ๊ฐ๋ฅํ ๊ฒ์ ์๋๊ณ ์ด๋ค ๊ฐ์ฒด๋ ์ง๋ ฌํ/์ญ์ง๋ ฌํ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
๊ฒ๋ค๊ฐ PropertyGrid ์ปจํธ๋กค๊ณผ XML ๊ฐ์ฒด๋ฅผ ์ฐ๋ํ๋ฉด XML ํธ์ง์ด ๋์ฑ ์ฉ์ดํ๊ณ ํ์ฉ์ฑ์ด ๋์์ง๋ ์ฅ์ ์ด ์์ต๋๋ค. ํ๋ฒ ์ฌ์ฉํด ๋ณด์ธ์.
'Programming > .Net' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[.Net] ์์ฑํ AI, C#์์ ๋๊ท๋ชจ ์ธ์ด ๋ชจ๋ธ(LLM) LLaMaSharp ์ฌ์ฉํ๊ธฐ(์์ ํฌํจ)
[.Net] ์์ฑํ AI, C#์์ ๋๊ท๋ชจ ์ธ์ด ๋ชจ๋ธ(LLM) LLaMaSharp ์ฌ์ฉํ๊ธฐ(์์ ํฌํจ)
2024.08.16 -
[.Net] WinForm UI ์ปจํธ๋กค ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ(Data Binding) ํํค์น๊ธฐ(์์ ํฌํจ)
[.Net] WinForm UI ์ปจํธ๋กค ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ(Data Binding) ํํค์น๊ธฐ(์์ ํฌํจ)
2024.03.24 -
[.Net] ML.NET์ ์ด์ฉํ ๋ฅ ๋ฌ๋ ๋ชจ๋ธ ์์ฑํ๊ธฐ - ์ด๋ฏธ์ง ๋ถ๋ฅ
[.Net] ML.NET์ ์ด์ฉํ ๋ฅ ๋ฌ๋ ๋ชจ๋ธ ์์ฑํ๊ธฐ - ์ด๋ฏธ์ง ๋ถ๋ฅ
2023.10.15 -
[.Net] ์ง์ฐ(Delay) ํจ์๋ค์ ํน์ง๊ณผ ์ฐจ์ด์ ์ ๋ฆฌ
[.Net] ์ง์ฐ(Delay) ํจ์๋ค์ ํน์ง๊ณผ ์ฐจ์ด์ ์ ๋ฆฌ
2023.01.09