[C# 강좌 - 30] XML 다루기 (1) - Reader


Study/C#  2012. 10. 3. 10:48

안녕하세요.  명월입니다.

이번 포스팅은 C#과 XML 통신에 대해 알아보겠습니다. 먼저 통신에 앞서 XML이 무엇인지 간략하게 알아보겠습니다.

XML(eXtensible Markup Languege)은 데이터 교환과 공유를 목적으로 1996년 W3C에서 정한 국제 표준안입니다. 그 당시 ISO에서 발표한 SGML 과 그 마크업을 바탕으로 웹기능을 특화시킨 HTML이 서서히 한계를 드러내자 W3C가 XML을 표준안으로 채택한 것입니다. XML 은 주로 다른 시스템, 특히 인터넷에 연결된 시스템끼리 데이터를 쉽게 주고 받을 수 있게 하여 HTML의 한계를 극복하기 위해 만들러 졌습니다.

XML의 구성요소는 구조(DTD와 스키마), 데이터(태그를 이용한 트리 형태로 표현),표현(XSL 이용 데이터 표현)으로 되어있습니다.

 

이번 포스팅은 XML에 대해 살펴보는 것이 아니라 XML 통신에 대한 포스팅이니 XML의 대한 자세한 설명은 MSDN링크를 걸어 놓겠습니다.

바로가기 - XML MSDN 바로가기

 

 

자 그럼 XML을 읽어드리기 위한 클래스에 대해서 알아보도록 하겠습니다.

C#에서는 보통 XMLTextReader 와 XmlNodeReader 두 클래스가 있으나 제가 사용하기에는 둘다 큰 차이는 없던걸로 기억합니다. 즉, 사용형식도 비슷하고 결과나 처리속도면도 거의 차이가 없습니다.

그럼 MSDN에서 두 클래스에 대해 찾아 보도록 하겠습니다.

 

바로가기 - XMLTextReader 바로가기

 

 

바로가기 - XmlNodeReader 바로가기

 

 

역시 설명보다는 하나의 예제로 설명하겠습니다.

(※ 예제는 블로그를 하시는 분이라면 각자 rss 가 있을 거라고 생각됩니다. rss는 XML형식으로 구성되어있으니 이 예제로 사용하시면 되고 없으신 분들은 제 피드 http://nowonbun.tistory.com/rss를 사용하시기 바랍니다.)

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Blog20121003
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program();
        }
        public Program() 
        {
            int count_page = 0;
            XmlTextReader xtr = new XmlTextReader("http://nowonbun.tistory.com/rss");
            while (xtr.Read()) 
            {
                if (count_page == 50)
                {
                    Console.Write("More...");
                    Console.ReadLine();
                    count_page = 0;
                }
                for (int i = 0; i < xtr.Depth; i++) 
                {
                    Console.Write(" ");
                }
                switch (xtr.NodeType) 
                { 
                    case XmlNodeType.Element:
                        Console.Write("<" + xtr.Name);
                        if (xtr.AttributeCount > 0) 
                        {
                            for (int i = 0; i < xtr.AttributeCount; i++)
                            {
                                xtr.MoveToAttribute(i);
                                Console.Write("{0}={1}", xtr.Name, xtr.Value);
                            }
                        }
                        Console.Write(">");
                        break;
                    case XmlNodeType.Text:
                        Console.WriteLine(xtr.Value);
                        break;
                    case XmlNodeType.EndElement:
                        Console.WriteLine("");
                        break;
                }
                count_page++;
            }
            xtr.Close();

            Console.WriteLine("Press any key...");
            Console.ReadLine();
        }
    }
}

 

 

XmlNodeReader는 아래와 같이 XmlDocument로 읽어 들여와서 XmlNodeReader 로 읽어 드리는 것 빼곤 사용하는 형식이 같습니다.

 

 

결과 화면입니다.

  

 

아래 코드는 유효성 검사식입니다. 유효성 검사식은 에러가 있는지 없는지 검사하는 식으로써 XML은 문서로 통신하는 방식 중에 하나 이므로 규격확인을 해야 잘못된 정보가 입력되지 않습니다.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Blog20121003
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program();
        }
        public Program()
        {
            int count_page = 0;

            XmlReaderSettings XRS = new XmlReaderSettings();
            XRS.ValidationType = ValidationType.DTD;
            XRS.ProhibitDtd = false;
            XRS.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(XRS_ValidationEventHandler);
            XmlReader xtr = XmlReader.Create("http://nowonbun.tistory.com/rss", XRS);
            while (xtr.Read())
            {
                if (count_page == 40)
                {
                    Console.Write("More...");
                    Console.ReadLine();
                    count_page = 0;
                }
                for (int i = 0; i < xtr.Depth; i++) 
                {
                    Console.Write(" ");
                }
                switch (xtr.NodeType)
                { 
                    case XmlNodeType.Element:
                        Console.Write("<" + xtr.Name);
                        if (xtr.AttributeCount > 0)
                        {
                            for (int i = 0; i < xtr.AttributeCount; i++)
                            {
                                xtr.MoveToAttribute(i);
                                Console.Write("{0}={1}", xtr.Name, xtr.Value);
                            }
                        }
                        Console.Write(">");
                        break;
                    case XmlNodeType.Text:
                        Console.WriteLine(xtr.Value);
                        break;
                    case XmlNodeType.EndElement:
                        Console.WriteLine("");
                        break;
                }
                count_page++;
            }
            xtr.Close();

            Console.WriteLine("Press any key...");
            Console.ReadLine();
        }
        void XRS_ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs e)
        {
            if (e.Exception != null)
            {
                Console.WriteLine("err:{0}, {1}-{2}",e.Exception.Message,e.Exception.LineNumber,e.Exception.LinePosition);
            }
            if (e.Severity == System.Xml.Schema.XmlSeverityType.Error)
            {
                Console.WriteLine("유효성 검증 에러!!!");
            }
            else if (e.Severity == System.Xml.Schema.XmlSeverityType.Warning)
            {
                Console.WriteLine("스키마가 존재하지 않음!!!");
            }
        }
    }
}

 

 

결과 화면입니다.

 

 

(※ Tistory에서 제공하는 Rss는 에러가 없는 XML이라서 유효성 검사에 걸리지 않습니다.^^)

 

참고소스 :Blog20121003.zip