Home Full Site
XElement : XML 쓰기

XML 데이타를 읽고 쓰는 또다른 방법 중의 하나로 XDocument와 XElement 클래스를 사용하는 방법이 있는데, 이는 System.Xml.Linq 네임스페이스에 있으며, LINQ To XML로서 XML에 대한 LINQ 쿼리를 지원하고 있다.

XML 데이타를 쓰기 위해서는 일반적으로 먼저 XDocument 객체를 생성하고 그 안에 XElement 노드들을 계층적인 방식으로 추가하면 됩니다. XML 문서 안에 Element는 XElement 클래스를 사용하고, Attribute는 XAttribute를, 코멘트는 XComment, XML Decoration은 XDecoration 클래스 등등을 사용하게 된다. 또한 부모 노드에서 자식 노드를 추가하기 위해는 XElement 객체의 Add() 메서드를 사용하여 추가하면 된다.

XElement 클래스 객체를 생성하는 방법의 특이한 점은 아래 예제에서 보이듯이 첫번째 파라미터로 Element명을 넣고, 나머지는 XAttribute, XElement 등등의 객체를 계속 추가할 수 있다는 점이다. 즉, 하나의 Element 내에 복수 개의 Element 노드들이 있으면, 이들을 계속 콤마로 분리해서 나열할 수 있다 (C#의 params 용법).

XML 데이타가 모두 완성되었으면, Save() 메서드를 써서 파일이나 스트림에 저장할 수 있다.

아래 예제는 XDocument / XElement를 써서 간단한 Employee 데이타를 XML로 저장하는 예이다.


예제

//using System.Xml.Linq;

XDocument xdoc = new XDocument(new XDeclaration("1.0", "UTF-16", null));
XElement xroot = new XElement("Employees");
xdoc.Add(xroot);

XElement xe1 = new XElement("Employee",
    new XAttribute("Id", "1001"),
    new XElement("Name", "Tim"),
    new XElement("Dept", "Sales")
);

XElement xe2 = new XElement("Employee",
    new XAttribute("Id", "1002"),
    new XElement("Name", "John"),
    new XElement("Dept", "HR")
);

xroot.Add(xe1);
xroot.Add(xe2);

xdoc.Save(@"C:\Temp\Emp.xml");

/* 출력파일 Emp.xml

<?xml version="1.0" encoding="utf-16"?>
<Employees>
  <Employee Id="1001">
    <!--Employee#1001-->
    <Name>Tim</Name>
    <Dept>Sales</Dept>
  </Employee>
  <Employee Id="1002">
    <Name>John</Name>
    <Dept>HR</Dept>
  </Employee>
</Employees>

*/



XElement : XML 읽기

XML 데이타를 파일 혹은 스트림으로부터 읽기 위해서는 XDocument.Load() (혹은 XElement.Load()) 메서드를 사용한다. XDocument로부터 로드된 경우, XDocument객체.Elements() 메서드는 XML의 루트노드 하나를 리턴하고, XDocument객체.Root.Elements() 는 루트노드 바로 밑의 자식 노드들을 리턴한다. (주: XElement.Load()를 사용한 경우 XElement객체.Elements() 는 루트노드 바로 밑의 자식 노드들을 리턴하게 된다.)

XElement 노드에서 자식 노드를 읽기 위해서는 Element(자식노드명) 메서드를 사용하여 자식노드의 XElement 객체를 얻어온 후 Value 속성을 읽으면 된다. 마찬가지로 XElement 노드에서 Attribute를 읽기 위해서는 Attribute(Attribute명) 메서드를 사용하여 XAttribute 객체를 얻어내고 이 XAttribute 객체의 Value 속성을 읽어오면 된다. XElement 클래스의 Elements() 메서드는 복수의 Element들을 리턴할 때 사용하고, Element() 메서드는 단일 Element를 리턴할 때 사용한다.

아래 예제는 위에서 생성 Emp.xml 파일을 읽어 들여 각 Employee의 데이타를 출력해 본 예이다.


예제

//using System.Xml.Linq;

XDocument xdoc = XDocument.Load(@"C:\Temp\Emp.xml");
//XElement xe = XElement.Load(@"C:\Temp\Emp.xml");

// <Employees> 노드 하나 리턴
IEnumerable<XElement> elems = xdoc.Elements();

// 복수 개의 <Employee> 노드들 리턴
IEnumerable<XElement> emps = xdoc.Root.Elements();
foreach (var emp in emps)
{
    string id = emp.Attribute("Id").Value;
    string name = emp.Element("Name").Value;
    string dept = emp.Element("Dept").Value;

    Console.WriteLine(id + "," + name + "," + dept);
}



LINQ to XML 쿼리

LINQ to XML은 XML 데이타에 대해 LINQ 쿼리를 사용하는 것으로 새롭게 설계된 XML 프로그래밍 방식이다. LINQ to XML은 메모리 상에 XML DOM을 생성하고, 유연한 LINQ 쿼리를 통해 데이타 쿼리를 쉽게 수행할 수 있다. 일반적으로 XElement.Elements()로 리턴되는 XML 데이타로부터 특정한 조건의 쿼리 혹은 정렬 등을 LINQ 쿼리를 사용하여 수행하게 된다. 아래 예제는 다양한 LINQ 쿼리에 대한 예로서 특정 노드를 검색하거나 복수 노드들을 필터링하는 코드이다.

예제

//using System.Xml.Linq;

XElement xElem = XElement.Load(@"C:\Temp\Emp.xml");

// Id가 1002인 Employee 검색
var result = from xe in xElem.Elements("Employee")
                where xe.Attribute("Id").Value == "1002"
                select xe;

var emp = result.SingleOrDefault();
if (emp != null)
{
    string name = emp.Element("Name").Value;
    string dept = emp.Element("Dept").Value;
    Console.WriteLine("{0},{1}", name, dept);
}

// Id가 1000 보다 큰 Employee들 검색
var emps = from xe in xElem.Elements("Employee")
            where int.Parse(xe.Attribute("Id").Value) > 1000
            select xe;

foreach (var e in emps)
{
    Console.WriteLine(e);
}

// LINQ 메서드 방식
var empList = xElem.Elements("Employee").Where(p => p.Element("Name").Value == "Tim");
foreach (var e in empList)
{
    Console.WriteLine(e);
}



© csharpstudy.com