ファイルではなく文字列に書き込む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警告を与えることに注意してくださいは、廃棄beacuse()メソッドは、オブジェクトにStringWriterに二回呼び出されます
ルカシュKosiak

113

リチャードが言っStringWriterたように、それは前進する方法です。ただし、問題が1つあります。デフォルトでStringWriterは、UTF-16であることを通知します。通常、 XMLはUTF-8です。これを修正するには、StringWriterをサブクラス化します。

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

これは、によって書かれた宣言に影響しXmlWriterます。もちろん、文字列をバイナリ形式で別の場所に書き出す場合は、修正したエンコーディングに一致するエンコーディングを使用してください。StringWriter。(上記のコードは常にUTF-8を想定しています。コンストラクターでエンコードを受け入れるより一般的なバージョンを作成するのは簡単です。)

次に使用します:

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

ジョン、writerそれは二度以上処分されていないのですか?
rasx 2010

2
@rasx:そうかもしれませんが、それは問題ではありません。
Jon Skeet、2010

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 2012年

1
ms.ToArray()これを試してもアイテムは返されません。x.Close()returnステートメントを内部のusingステートメントのすぐ外側に追加または移動する必要がありました。
リッチC

utf8.GetString(ms.GetBuffer()、0、(int)ms.Length);を実行します。作業?
brianary 2013

1
@リッチC-ストリームがフラッシュされなかったためと思われます。XmlTextWriterは、usingステートメントの外で破棄され、フラッシュされます。
yourbuddypal 2014年

13

使用StringBuilder

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

1

皆さんはxmlWriter.Close()およびxmlWriter.Dispose()を呼び出すことを忘れないでください。そうしないと、文字列の作成が完了しません。空の文字列になります


心配しないでください。ステートメントを使用すると、オブジェクトの破棄が処理されます。

これは2009年からの質問です。したがって、今すぐ回答を提供することの価値は、同様の問題を抱えている可能性のある将来のユーザーのためになるでしょう。したがって、このような古い質問への回答は、問題を明確に特定し、解決策を説明/提供できる場合にのみ提供してください。OPが先に進んでいる可能性が高いので、OPを会話に参加させようとすることは通常無意味です。
MikeC 2016

私はこれらすべての例を検討していましたが、なぜ空の文字列を取得するのでしょうか。xmlWriter.Close()解決策でした。
ラファウ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.