2010-10-06 1 views
32

Desidero essere in grado di scrivere XML in una stringa con la dichiarazione e con la codifica UTF-8. Questo sembra molto difficile da realizzare.Forza XDocument per scrivere su String con codifica UTF-8

Ho letto un po 'e ho provato alcune delle risposte popolari per questo, ma hanno tutti problemi. Il mio codice corrente viene emesso correttamente come UTF-8 ma non mantiene la formattazione originale di XDocument (cioè indent/spazio bianco)!

Qualcuno può offrire qualche consiglio per favore?

XDocument xml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), xelementXML); 

MemoryStream ms = new MemoryStream(); 
using (XmlWriter xw = new XmlTextWriter(ms, Encoding.UTF8)) 
{ 
    xml.Save(xw); 
    xw.Flush(); 

    StreamReader sr = new StreamReader(ms); 
    ms.Seek(0, SeekOrigin.Begin); 

    String xmlString = sr.ReadToEnd(); 
} 

L'XML richiede la formattazione di essere identico al modo in cui .ToString() formatterebbe è cioè

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<root> 
    <node>blah</node> 
</root> 

Quello che sto vedendo è attualmente

<?xml version="1.0" encoding="utf-8" standalone="yes"?><root><node>blah</node></root> 

Aggiornamento ho è riuscito a farlo funzionare aggiungendo le impostazioni XmlTextWriter ... Sembra MOLTO goffo !

MemoryStream ms = new MemoryStream(); 
XmlWriterSettings settings = new XmlWriterSettings(); 
settings.Encoding = Encoding.UTF8; 
settings.ConformanceLevel = ConformanceLevel.Document; 
settings.Indent = true; 
using (XmlWriter xw = XmlTextWriter.Create(ms, settings)) 
{ 
    xml.Save(xw); 
    xw.Flush(); 

    StreamReader sr = new StreamReader(ms); 
    ms.Seek(0, SeekOrigin.Begin); 
    String blah = sr.ReadToEnd(); 
} 
+0

Qual 'formattazione'? Non hai detto nulla sulla formattazione! – AakashM

+0

Il solito spazio/formattazione che si ottiene se si giunge a un '.ToString()' su un 'XDocument' o' XElement' – Chris

+0

Fornire un documento di input di esempio in modo da poter verificare le risposte. –

risposta

53

Prova questo:

using System; 
using System.IO; 
using System.Text; 
using System.Xml.Linq; 

class Test 
{ 
    static void Main() 
    { 
     XDocument doc = XDocument.Load("test.xml", 
             LoadOptions.PreserveWhitespace); 
     doc.Declaration = new XDeclaration("1.0", "utf-8", null); 
     StringWriter writer = new Utf8StringWriter(); 
     doc.Save(writer, SaveOptions.None); 
     Console.WriteLine(writer); 
    } 

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

Naturalmente, non ci hai mostrato come si sta costruendo il documento, il che rende difficile per testare ... Ho appena provato con un costruito a mano XDocument e che contiene anche lo spazio bianco pertinente.

+0

Funziona a meraviglia, grazie - non c'è modo di ottenere la codifica ordinata senza ereditare da StringWriter? – Chris

+0

@Chris: È * possibile * che ci sia un modo per far sì che il sovraccarico di TextWriter ignori la codifica pubblicizzata da TextWriter, ma ho trovato che questo è un trucco molto semplice per completare il lavoro. (Ne hai solo bisogno in un posto ...) –

+0

Sì, mi piace - è MOLTO meglio del metodo che ho trovato. Grazie – Chris

2

XmlWriterSettings provare:

XmlWriterSettings xws = new XmlWriterSettings(); 
xws.OmitXmlDeclaration = false; 
xws.Indent = true; 

e passarlo su come

using (XmlWriter xw = XmlWriter.Create(sb, xws))