2009-06-05 23 views
98

Ho un servizio WCF che deve restituire una stringa di XML. Ma sembra che lo scrittore voglia solo creare un file, non una stringa. Ho provato:XmlWriter da scrivere su una stringa anziché su un file

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

Questo genera un errore che dice nextXMLstring non ha una percorso di file. Vuole qualcosa tipo:

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

Come posso creare il mio XML e quindi restituirlo come stringa ??

Grazie !!

risposta

178

È necessario creare un StringWriter e passarlo a XmlWriter.

L'overload di stringhe di XmlWriter.Create è per un nome file.

E.g.

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


    } 
    return sw.ToString(); 
} 
+2

@Will: ripristinato la modifica. XmlTextWriter.Close() arriverà allo stream, quindi vuoi che succeda prima di estrarre la stringa. (Poco differenza in questo caso, ma preferisco farlo in modo coerente perché la semantica dei flussi delle classi * Writer e Stream non è sempre chiaramente documentata.) – Richard

+1

Solo un commento per le persone che usano questo. Se ti capita di omettere l'uso di() e invece dichiari il tuo XmlWriter normalmente assicurati di chiamare xw.Flush prima di chiamare sw.ToString() altrimenti potresti non ottenere tutto il contenuto! (Ovviamente meglio usare le parentesi usando ...) – Ravendarksky

+0

Ricorda che il seguente codice dà l'avviso CA2202 durante l'analisi del codice, perché il metodo Dispose() verrà chiamato due volte sull'oggetto StringWriter –

100

Come ha detto Richard, StringWriter è la via da seguire. C'è un limite, tuttavia: per impostazione predefinita, StringWriter si pubblicizzerà come in UTF-16. Solitamente XML è in UTF-8. È possibile risolvere questo sottoclasse StringWriter;

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

Ciò influirà sulla dichiarazione scritta da XmlWriter. Naturalmente, se si scrive la stringa altrove in formato binario, assicurarsi di utilizzare una codifica che corrisponda a qualsiasi codifica che si risolve per lo StringWriter. (Il codice di cui sopra assume sempre UTF-8: è banale per fare una versione più generale che accetta una codifica nel costruttore.)

Farebbe quindi usare:

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

+1 Questo è spesso trascurato e importante da sapere . –

+0

Questa sarebbe la "codifica della codifica della sovrascrittura pubblica". – Einar

+0

@Einar: Grazie, risolto. –

23

So che questo è vecchio e rispose, ma qui c'è un altro modo per farlo. Soprattutto se non si desidera che il BOM UTF8 all'inizio della stringa e si desidera che il testo rientrato:

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())' è una semplificazione al tuo ritorno. – SliverNinja

+0

@SliverNinja Bello! Aggiunto. – brianary

+1

'ms.ToArray()' non restituisce elementi quando ho provato questo. Dovevo aggiungere 'x.Close()' o spostare l'istruzione return appena fuori dall'istruzione using interna. –

8

Uso StringBuilder:

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

ragazzi non dimenticare di chiamare xmlWriter.Close() e xmlWriter.Dispose(), altrimenti la stringa non terminerà la creazione. Sarà solo una stringa vuota

+0

Non preoccuparti, l'uso della dichiarazione gestirà lo smaltimento dell'oggetto. –

+0

Questa è una domanda del 2009. Quindi, il valore nel fornire una risposta ora sarebbe per gli utenti futuri che potrebbero avere problemi simili. Di conseguenza, le risposte a vecchie domande come questa dovrebbero essere fornite solo se possono identificare chiaramente il problema e spiegare/fornire una soluzione. Di solito è inutile cercare di coinvolgere l'OP in una conversazione poichè è probabile che si siano trasferiti. – MikeC

Problemi correlati