2009-06-05 13 views
98

Ich habe einen WCF-Dienst, der eine XML-Zeichenfolge zurückgeben muss. Aber es scheint, als ob der Schreiber nur eine Datei und keine Zeichenfolge erstellen möchte. Ich habe versucht:XmlWriter zum Schreiben in eine Zeichenfolge statt in eine Datei

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

Dies erzeugt einen Fehler, der besagt, dass nextXMLstring nicht einen Dateipfad hat. Es möchte etwas wie:

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

Wie kann ich meine XML aufbauen und dann als String zurückgeben ??

Danke !!

Antwort

178

Sie müssen einen StringWriter erstellen und diesen an den XmlWriter übergeben.

Die Zeichenfolgeüberladung von XmlWriter.Create ist für einen Dateinamen.

z.

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


    } 
    return sw.ToString(); 
} 
+2

@Will: Rolled Ihre Änderung. XmlTextWriter.Close() wird mit dem Stream gespült, also sollte das vor dem Extrahieren der Zeichenfolge geschehen. (Kleiner Unterschied in diesem Fall, aber bevorzugen Sie dies konsequent zu tun, weil Flush-Semantik von * Writer- und Stream-Klassen nicht immer eindeutig dokumentiert ist.) – Richard

+1

Nur ein Kommentar für Leute, die dies verwenden. Wenn Sie die Verwendung von using() weglassen und stattdessen Ihren XmlWriter normal deklarieren, dann stellen Sie sicher, dass Sie xw.Flush aufrufen, bevor Sie sw.ToString() aufrufen, sonst erhalten Sie möglicherweise nicht alle Inhalte! (Offensichtlich besser, die Verwendung von Klammern ...) – Ravendarksky

+0

Beachten Sie, dass der folgende Code CA2202 Warnung während der Code-Analyse gibt, weil Dispose() -Methode zweimal auf StringWriter-Objekt aufgerufen wird –

100

Wie Richard sagte, StringWriter ist der Weg nach vorn. Es gibt jedoch einen Haken: Standardmäßig wird StringWriter als UTF-16-Datei angezeigt. Normalerweise XML ist in UTF-8. Sie können dies beheben, indem Sie StringWriter subclassing;

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

Dies wirkt sich auf die von XmlWriter geschriebene Deklaration aus. Wenn Sie die Zeichenfolge an anderer Stelle in Binärform schreiben, stellen Sie sicher, dass Sie eine Codierung verwenden, die mit der Codierung übereinstimmt, die Sie für StringWriter beheben. (Der obige Code geht immer davon aus UTF-8, es trivial ist eine allgemeinere Version zu machen, die eine Codierung im Konstruktor akzeptiert.)

Sie würden dann verwenden:

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

+1 Dies ist oft übersehen und wichtig zu wissen . –

+0

Das wäre 'öffentliche Überschreibung Kodierung Kodierung'. – Einar

+0

@Einar: Danke, behoben. –

23

Ich weiß, das ist alt und beantwortet, aber hier ist ein anderer Weg, es zu tun. Vor allem, wenn Sie nicht wollen, die UTF-8 BOM am Beginn der Zeichenfolge und Sie wollen, dass der Text eingerückt:

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())' ist eine Vereinfachung bei Ihrer Rückkehr. – SliverNinja

+0

@SliverNinja Schön! Hinzugefügt. – brianary

+1

'ms.ToArray()' gibt keine Elemente zurück, als ich dies versuchte. Musste 'x.Close()' hinzufügen oder die return-Anweisung direkt außerhalb der inneren using-Anweisung verschieben. –

8

Verwendung StringBuilder:

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

Jungs nicht vergessen, xmlWriter.Close zu nennen() und xmlWriter.Dispose(), andernfalls wird die Erstellung der Zeichenfolge nicht abgeschlossen. Es wird nur eine leere Zeichenfolge sein

+0

Keine Sorge, mit der Anweisung wird die Entsorgung des Objekts erledigt. –

+0

Dies ist eine Frage aus dem Jahr 2009. Der Wert einer Antwort wäre also für zukünftige Benutzer, die ähnliche Probleme haben könnten. Folglich sollten Antworten auf alte Fragen wie diese nur dann gegeben werden, wenn sie das Problem klar identifizieren und eine Lösung erklären/zur Verfügung stellen können. Es ist normalerweise fruchtlos, zu versuchen, das OP in ein Gespräch einzubeziehen, da sie wahrscheinlich weitergezogen sind. – MikeC

Verwandte Themen