파일 대신 문자열에 쓰는 XmlWriter


118

XML 문자열을 반환해야하는 WCF 서비스가 있습니다. 하지만 작가는 문자열이 아닌 파일 만 만들고 싶어하는 것 같습니다. 나는 시도했다 :

string nextXMLstring = "";
using (XmlWriter writer = XmlWriter.Create(nextXMLstring))

이것은 nextXMLstring에 파일 경로가 없다는 오류를 생성합니다. 다음과 같은 것을 원합니다.

using (XmlWriter writer = XmlWriter.Create("nextXMLstring.xml"))

내 XML을 구축 한 다음 문자열로 반환하려면 어떻게해야합니까 ??

감사!!

답변:


217

StringWriter를 만들고이를 XmlWriter에 전달해야합니다.

XmlWriter.Create의 문자열 오버로드는 파일 이름에 대한 것입니다.

using (var sw = new StringWriter()) {
  using (var xw = XmlWriter.Create(sw)) {
    // Build Xml with xw.


  }
  return sw.ToString();
}

2
@Will : 변경 사항을 롤백했습니다. XmlTextWriter.Close ()는 스트림으로 플러시되므로 문자열을 추출하기 전에이를 수행하려고합니다. (이 경우 약간의 차이가 있지만 * Writer 및 Stream 클래스의 플러시 의미가 항상 명확하게 문서화되지 않았기 때문에 일관되게 수행하는 것이 좋습니다.)
Richard

1
이것을 사용하는 사람들을위한 단지 코멘트. using ()을 생략하고 대신 XmlWriter를 정상적으로 선언 한 경우 sw.ToString ()을 호출하기 전에 xw.Flush를 호출해야합니다. 그렇지 않으면 모든 콘텐츠를 얻지 못할 수 있습니다! (물론 더 나은 ... 사용하여 브래킷을 사용)
Ravendarksky

다음 코드는 코드 분석 중에 CA2202 경고를 제공합니다. Dispose () 메서드가 StringWriter 개체에서 두 번 호출되기 때문입니다
Łukasz Kosiak

113

Richard가 말했듯 StringWriter이 앞으로 나아갈 길입니다. 그러나 한 가지 문제가 있습니다. 기본적 StringWriter으로 UTF-16으로 자신을 광고합니다. 일반적으로 XML은 UTF-8입니다. StringWriter를 서브 클래 싱하여이 문제를 해결할 수 있습니다.

public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding
    {
         get { return Encoding.UTF8; }
    }
}

에서 작성한 선언에 영향을 미칩니다 XmlWriter. 물론 이진 형식으로 다른 곳에 문자열을 작성하는 경우 .NET Framework에 대해 수정 한 인코딩과 일치하는 인코딩을 사용해야합니다 StringWriter. (위의 코드는 항상 UTF-8을 가정합니다. 생성자에서 인코딩을 허용하는보다 일반적인 버전을 만드는 것은 간단합니다.)

그런 다음 다음을 사용합니다.

using (TextWriter writer = new Utf8StringWriter())
{
    using (XmlWriter xmlWriter = XmlWriter.Create(writer))
    {
        ...
    }
    return writer.ToString();
}

Jon, 그게 writer두 번 이상 처리되지 않는 것이 확실 합니까?
rasx 2010

2
@rasx : 그럴 수도 있지만 그건 중요하지 않습니다.
Jon Skeet

30

나는 이것이 오래되고 답이 있다는 것을 알고 있지만 여기에 다른 방법이 있습니다. 특히 문자열 시작 부분에 UTF8 BOM을 원하지 않고 텍스트를 들여 쓰고 싶은 경우 :

using (var ms = new MemoryStream())
using (var x = new XmlTextWriter(ms, new UTF8Encoding(false)) 
                   { Formatting = Formatting.Indented })
{
     // ...
     return Encoding.UTF8.GetString(ms.ToArray());
}

3
Encoding.UTF8.GetString(ms.ToArray())귀하의 반환에 대한 단순화입니다.
SliverNinja-MSFT

1
ms.ToArray()내가 이것을 시도했을 때 항목을 반환하지 않습니다. x.Close()내부 using 문 외부에 return 문 을 추가 하거나 이동해야했습니다.
Rich C

utf8.GetString (ms.GetBuffer (), 0, (int) ms.Length); 작업?
brianary 2013

1
@Rich C-스트림이 플러시되지 않았기 때문이라고 생각합니다. XmlTextWriter는 using 문 외부에서 삭제되어 플러시됩니다.
yourbuddypal

13

사용 StringBuilder:

var sb = new StringBuilder();
    using (XmlWriter xmlWriter = XmlWriter.Create(sb))
    {
        ...
    }
return sb.ToString();

1

사람들은 xmlWriter.Close () 및 xmlWriter.Dispose ()를 호출하는 것을 잊지 마십시오. 그렇지 않으면 문자열 생성이 완료되지 않습니다. 빈 문자열이됩니다.


걱정하지 마세요. using 문은 개체의 처리를 처리합니다.

이것은 2009 년의 질문입니다. 따라서 지금 답변을 제공하는 것의 가치는 유사한 문제가있을 수있는 미래 사용자를위한 것입니다. 따라서 이와 같은 오래된 질문에 대한 답변은 문제를 명확하게 식별하고 해결책을 설명 / 제공 할 수있는 경우에만 제공되어야합니다. OP가 전진했을 가능성이 높기 때문에 대화에 OP를 참여시키는 것은 일반적으로 무익합니다.
MikeC 2016

이 모든 예제를 살펴보고 왜 빈 문자열이 발생하는지 궁금했습니다. xmlWriter.Close()해결책이었습니다.
Rafał Ryszkowski

-1

여기서 가장 간단하고 빠른 해결책은 다음과 같습니다.

StringBuilder sb = new StringBuilder();

using (var writer = XmlWriter.Create(sb, settings))
{
    ... // Whatever code you have/need :)

    sb = sb.Replace("encoding=\"utf-16\"", "encoding=\"utf-8\""); //Or whatever uft you want/use.
    //Before you finally save it:
    File.WriteAllText("path\\dataName.xml", sb.ToString());
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.