XmlWriter Encoding

XmlWriter Encoding 

우리는 많은 상황에서 Xml을 사용합니다. 아주 유용한 구석이 많은 포멧이죠. .Net Xml을 사용할 수 있는 다양한 방법을 제공합니다. 그 중에서 Xml 문서를 작성할 때는 주로 XmlWriter 클래스를 사용하죠. 그런데 이 XmlWriter 클래스를 사용할 경우에는 주의해야 할 부분이 있습니다. 아마 이미 경험하신 분들도 계실 텐데바로 Encoding 문제입니다. 그럼 왜 Encoding이 문제가 되는지 간단한 샘플 코드를 통해서 살펴 보겠습니다.

 

static void Main(string[] args)
{
    StringWriter sw = new StringWriter();
    XmlWriter xw = XmlWriter.Create(sw);

    xw.WriteStartDocument();
    xw.WriteStartElement("result");
    xw.WriteElementString("item", "test1");
    xw.WriteElementString("item", "test2");
    xw.WriteEndElement();
    xw.WriteEndDocument();

    xw.Flush();

    string xmlDoc = sw.GetStringBuilder().ToString();
}
 

 

아주 간단한 코듭니다. 그리고 물론 오류도 없고, 의도한 대로 Xml 문서도 잘 생성합니다. 그럼 이 문서의 결과를 한번 보겠습니다.

 

 

 

보기에도 별 문제는 없어 보입니다. 그런데.. 잘 생각해 보면 한 가지가 눈에 띌 것입니다. 바로 앞서 말씀 드린 것과 같이 Encoding이 그렇습니다. 이 문서의 encoding을 보면 utf-16으로 돼있는 것을 확인할 수 있는데.. 이 부분이 바로 XmlWriter를 사용할 때 주의해야 할 부분입니다.

 XmlWriter 클래스는 StringWriter 객체를 통해 StringWriter 내부적으로 생성하는 StringBuilder 클래스에 Xml 포맷으로 직렬화 데이터를 전달하고 StringBuilder 데이터를 메모리 버퍼에 저장합니다. 문제는 여기서 발생합니다. 왜냐하면 .Net 런타임(CLR) Char 타입의 데이터를 16bit 형식인 UTF16으로 메모리에 저장하기 때문에 앞에서 StringWriter 클래스를 통해 메모리에 저장된 Xml 데이터 또한 utf-16 포맷으로 저장된 것입니다. 이것은 다음의 주소에 명시되어 있습니다.http://msdn2.microsoft.com/ko-kr/library/system.string(en-us,vs.71).aspx 

이로 인해 데이터를 Xml 포멧으로 직렬화하는 과정에서 utf-8 형식으로 전달 받은 데이터를 Deserialize할 때는 오류가 발생합니다. XmlWriter Xml 데이터를 utf-16으로 생성하기 때문이죠.

 

아마 몇몇 분은 XmlWriterSetting 클래스를 사용해면 되지 않느냐 하실지도 모르겠습니다. 바로 다음처럼요..

 
StringWriter sw = new StringWriter();
XmlWriterSettings setting = new XmlWriterSettings();
setting.Encoding = Encoding.UTF8;
XmlWriter xw = XmlWriter.Create(sw, setting);
 

하지만 문자열로 Xml 문서를 생성할 경우에는, 이것으로 문제가 해결되지 않습니다. 그럼 어떻게 해야 하느냐이렇게 하시면 됩니다.

 

public class UTF8StringWriter : StringWriter
{
    Encoding encoding;
    public UTF8StringWriter(Encoding encoding)
    {
        this.encoding = encoding;
    }

    public override Encoding  Encoding
    {
        get
        {
          return this.encoding;
        }
    }
}

 

StringWriter 클래스를 상속받은 클래스를 하나 정의합니다. 그리고 Encoding 속성을 override해서 생성자로 전달한 Encoding을 리턴합니다. 아주 심플합니다. 냐햐햐햐 ~

그리고 이렇게 생성한 클래스를 사용해서 다음과 같이 코딩합니다.

 

UTF8StringWriter sw = new UTF8StringWriter(Encoding.UTF8);
XmlWriter xw = XmlWriter.Create(sw);

// 나머지 코드는 동일

 

사용 방법 역시 아주 간단합니다. 이렇게 코딩한 결과를 살펴 보면 다음과 같습니다.

 

 

결과를 확인해 보면 알 수 있듯이, Xml 문서의 encoding 속성이 utf-8로 변경됐습니다. 원하는 결과를 얻게 된 것이죠. 하지만 한가지 참고해야 할 것이 XmlWriterSetting 클래스인데.. 그럼 이 클래스를 사용해도 Encoding 속성은 변경할 수 없는 거냐? 하는 겁니다. 그렇진 않죠. 그러려면 이 클래스를 만들 이유가 없었겠죠. XmlWriterSetting 클래스는 Xml 문서를 직접 문자열로 쓰는 클래스에는 사용할 수 없지만 Stream을 직접 다루는 상황에서는 충분히 사용 가능합니다. 다음과 같은 경우가 될 수 있겠죠.

 
MemoryStream ms = new MemoryStream();
XmlWriterSettings setting = new XmlWriterSettings();
setting.Encoding = Encoding.UTF8;
XmlWriter xw = XmlWriter.Create(ms, setting);
 

그럼 여기까지 해서 설명을 마무리 지을까 합니다. 오늘 아침 출근길에 라디오를 들어보니, 하루 종일 더운 날씨가 계속 될 거라고 하네요. 점심에 시원한 냉 메밀이나 김치말이 국수 어떠신지요. ^o^ 감사합니다.

 

posted by zmeun

  

평점 3.0 / 2회 참여

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Add comment


 

biuquote
Loading



Search

Recent comments