XmlWriter Dosyaya Yazmak Yerine Bir Dizeye Yazacak


118

XML dizesi döndürmesi gereken bir WCF hizmetim var. Ancak görünen o ki, yazar bir dizge değil, yalnızca bir dosya oluşturmak istiyor. Denedim:

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

Bu, nextXMLstring'in bir dosya yoluna sahip olmadığını belirten bir hata oluşturur. Şöyle bir şey istiyor:

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

XML'imi nasıl oluşturabilirim ve sonra onu bir dizge olarak döndürebilirim?

Teşekkürler!!

Yanıtlar:


217

Bir StringWriter oluşturmanız ve bunu XmlWriter'a iletmeniz gerekir.

XmlWriter.Create'in dize aşırı yüklemesi bir dosya adı içindir.

Örneğin

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


  }
  return sw.ToString();
}

2
@Will: Değişikliğinizi geri aldım. XmlTextWriter.Close () akışa boşaltılır, bu nedenle dizeyi çıkarmadan önce bunun olmasını isteyin. (Bu durumda çok az fark var, ancak bunu tutarlı bir şekilde yapmayı tercih edin çünkü * Writer ve Stream sınıflarının flush semantiği her zaman açıkça belgelenmez.)
Richard

1
Bunu kullanan kişiler için sadece bir yorum. Kullanmayı () atlarsanız ve bunun yerine XmlWriter'ınızı normal olarak bildirirseniz, sw.ToString () 'i çağırmadan önce xw.Flush'ı çağırdığınızdan emin olun yoksa tüm içeriği alamayabilirsiniz! (Parantezleri kullanmak açıkça daha iyi ...)
Ravendarksky

Aşağıdaki kodun kod analizi sırasında CA2202 uyarısı verdiğini unutmayın, beacuse Dispose () yöntemi StringWriter nesnesinde iki kez çağrılacaktır
Łukasz Kosiak

113

Richard'ın dediği gibi, StringWriterileriye giden yoldur. Bununla birlikte, bir sorun var: varsayılan olarak, StringWriterkendisini UTF-16'da ilan edecek. XML genellikle UTF-8'dir. StringWriter'ı alt sınıflandırarak bunu düzeltebilirsiniz;

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

Bu, tarafından yazılan beyanı etkileyecektir XmlWriter. Elbette, dizeyi başka bir yere ikili biçimde yazarsanız StringWriter,. (Yukarıdaki kod her zaman UTF-8 olduğunu varsayar; yapıcıda bir kodlamayı kabul eden daha genel bir sürüm yapmak önemsizdir.)

Daha sonra şunları kullanırsınız:

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

Jon, bunun writerbirden çok kez elden çıkarılmadığına emin misin ?
rasx

2
@rasx: Olabilir - ama bu önemli değil.
Jon Skeet

30

Bunun eski ve yanıtlanmış olduğunu biliyorum, ama işte bunu yapmanın başka bir yolu. Özellikle UTF8 BOM'un dizenizin başında olmasını istemiyorsanız ve metnin girintili olmasını istiyorsanız:

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())dönüşünüzde basitleştirmedir.
SliverNinja - MSFT

1
ms.ToArray()Bunu denediğimde hiçbir öğe döndürmüyor. x.Close()Return ifadesini iç using ifadesinin hemen dışına eklemek veya taşımak zorunda kaldım .
Zengin C

Utf8.GetString (ms.GetBuffer (), 0, (int) ms.Length); iş?
brianary

1
@Rich C - Bunun yayınınızın temizlenmemesinden kaynaklandığından şüpheleniyorum. XmlTextWriter, floş olmasına neden olacak kullanma ifadesinin dışında bırakılırdı.
popülasyonunuz

14

kullanım StringBuilder :

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

1

Çocuklar xmlWriter.Close () ve xmlWriter.Dispose () 'u çağırmayı unutmazlar, yoksa dizginiz yaratmayı bitirmez. Sadece boş bir dize olacak


Endişelenmeyin, ifade kullanmak nesnenin elden çıkarılmasını sağlayacaktır.

Bu, 2009'dan kalma bir sorudur. Dolayısıyla, şimdi bir yanıt sağlamanın değeri, benzer sorunları olabilecek gelecekteki kullanıcılar için olacaktır. Sonuç olarak, bunun gibi eski sorulara cevaplar, ancak sorunu açıkça belirleyebildikleri ve bir çözüm sağlayabildikleri takdirde verilmelidir. OP'yi bir sohbete dahil etmeye çalışmak genellikle sonuçsuzdur, çünkü muhtemelen devam etmişlerdir.
MikeC

Tüm bu örnekleri gözden geçiriyordum ve neden boş dizeler aldığımı merak ediyordum. xmlWriter.Close()çözüm buydu.
Rafał Ryszkowski

-1

Bence buradaki en basit ve en hızlı çözüm şudur:

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());
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.