Home Full Site
XML을 순차적으로 읽고 쓰기

XML을 읽고 쓰는 전통적인 방식으로 XmlReader, XmlWriter 클래스(System.Xml)를 사용하는 방식이 있는데, 이 클래스들은 XML을 순차적으로 한 노드씩 읽고 쓰게 된다. XML DOM 방식을 사용하는 XmlDocument 클래스와 비교해 보면, XmlDocument가 파일을 오픈하면서 모든 XML 내용을 메모리로 로딩하는 반면, XmlReader은 Forward-only 방식으로 캐쉬없이 순차적으로 처리한다는 차이가 있다. XmlReader, XmlWriter는 XML DOM 방식보다 사용이 불편하긴 하지만 사이즈가 큰 XML 파일을 핸들링할 때 유용하다. 예를 들어, 2 GB의 XML 파일을 핸들링 한다면, XmlReader/XmlWriter가 더 적합할 것이다.



XmlWriter : XML 파일 쓰기

XmlWriter 클래스는 XML 파일을 순차적으로 쓸 때 사용하는 클래스이다. XmlWriter 클래스는 Abstract클래스로서 이를 구현한 클래스로 XmlTextWriter 클래스가 있지만, XmlTextWriter를 사용하는 대신 XmlWriter.Create() 메서드를 사용할 것을 권장한다 (새로운 기능을 더 지원함).

XML 파일을 생성하기 위해서는 XmlWriter.Create(파일명) 과 같이 Create() 정적메서드에 XML 파일명을 지정하면 된다. XML을 실제 쓰기 위해서 여러 종류의 Write* 메서드들이 있는데, 가장 먼저 새로운 XML 문서를 시작하기 위해 WriteStartDocument() 를 사용하고, 이 메서드와 Pair를 이루는 WriteEndDocument() 메서드를 마지막에 써주게 된다. 문서가 시작된 후 WriteStartElement() 메소드를 써서 새로운 XML Element를 시작하면서 새 XML 노드를 만들게 되고, 물론 이와 Pair를 이루는 WriteEndElement() 를 매칭해서 나중에 써주게 된다. WriteStartElement()와 WriteEndElement() 사이에는 여러 자식 노드(자식 Element)들을 만들 수 있다. 자식노드는 또한 또다른 자식노드들을 Nested 방식으로 계속 가질 수 있다. 만약 하나의 Element가 자식이 없는 경우, 간단히 WriteElementString() 메서드를 사용할 수 있다. 또한 Element가 Attribute 를 갖으면 이는 WriteStartElement()와 WriteEndElement() 사이에 WriteAttributeString() 메서드를 사용하여 지정할 수 있다.

아래 예제는 간단한 Employee 데이타를 XML로 작성한 예이다.


예제

// using System.Xml;

using (XmlWriter wr = XmlWriter.Create(@"C:\Temp\Emp.xml"))
{
    wr.WriteStartDocument();
    wr.WriteStartElement("Employees");

    // Employee#1001
    wr.WriteStartElement("Employee");
    wr.WriteAttributeString("Id", "1001");  // attribute 쓰기
    wr.WriteElementString("Name", "Tim");   // Element 쓰기
    wr.WriteElementString("Dept", "Sales");
    wr.WriteEndElement();

    // Employee#1002
    wr.WriteStartElement("Employee");
    wr.WriteAttributeString("Id", "1002");
    wr.WriteElementString("Name", "John");
    wr.WriteElementString("Dept", "HR");
    wr.WriteEndElement();

    wr.WriteEndElement();
    wr.WriteEndDocument();
}

/* 출력파일 Emp.xml

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

*/



XmlReader : XML 파일 읽기

XmlReader 클래스는 XML 파일을 순차적으로 읽을 때 사용하는 클래스이다. XmlReader 클래스는 Abstract클래스로서 이를 구현한 클래스로 XmlTextReader 클래스가 있지만, XmlWriter와 마찬가지로 XmlTextReader를 사용하는 대신 XmlReader.Create() 메서드를 사용할 것을 권장한다.

XML 데이타를 읽기 위해 여러 종류의 Read* 메서드들이 있는데, 모두 뒤로 이동할 수는 없으며 앞으로 계속 전진하면서(forward only) 처리하게 된다. Read 메서드들 중 몇가지를 살펴보면, 우선 Read()는 XML 파일을 오픈한 후 처음 호출해야 하는 메서드인데, 이 메서드 호출로 XML의 첫 노드로 이동하게 된다. Read() 메서드는 순차적으로 XML 노드들로 이동하면서 true를 리턴하는데, 만약 XML 의 끝을 만나면 false 를 리턴한다.

XML Element의 Attribute 를 읽기 위해서는 GetAttribute() 메서드를 사용할 수 있으며, 또는 (아래 예제에서 처럼) 좀 더 간단하게 인덱서를 사용할 수 있다.

XML Element의 내용을 문자열로 읽기 위해서는 ReadElementContentAsString() 메서드를 사용한다 (주: 이 메서드와 비슷한 ReadElementString() 메서드가 있는데, ReadElementContentAsString() 메서드를 사용할 것을 권장). 이 메서드는 현재 Element 위치에 있다는 전제에서 Content를 읽고 다음 노드로 이동한다.

아래 예제는 위의 XmlWriter 에서 생성한 XML 파일을 읽는 예이다.


예제

using (XmlReader rd = XmlReader.Create(@"C:\Temp\Emp.xml"))
{
    while(rd.Read())
    {
        if (rd.IsStartElement())
        {
            if (rd.Name == "Employee")
            {
                // attribute 읽기                            
                string id = rd["Id"]; // rd.GetAttribute("Id");

                rd.Read();   // 다음 노드로 이동        
                                                
                // Element 읽기
                string name = rd.ReadElementContentAsString("Name", "");
                string dept = rd.ReadElementContentAsString("Dept", "");

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



© csharpstudy.com