2009-09-15 15 views
12

Sto usando questo metodo per serializzare il mio oggetto:Come controllo la parte <?xml ?> della serializzazione xml con .NET?

public static string XmlSerialize(object o) 
{ 
    var stringWriter = new StringWriter(); 
    var xmlSerializer = new XmlSerializer(o.GetType()); 
    xmlSerializer.Serialize(stringWriter, o); 
    string xml = stringWriter.ToString(); 
    stringWriter.Close(); 
    return xml; 
} 

Rende XML che inizia così:

<?xml version="1.0" encoding="utf-16"?> 
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

Ma voglio farlo sembrare come questo:

<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?> 
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

Quindi, come posso cambiare la codifica in Windows-1252 e impostare standalone = sì? Inoltre, come si ottiene l'oggetto per escludere il valore xmlns?

Ho visto un paio di domande simili, come this one, ma speravo che potesse essere più semplice per me, magari impostando alcuni attributi da qualche parte?

Aggiornamento 2: dopo aver letto la risposta e i commenti di John e aver pensato di più, ho deciso di creare un secondo metodo. Non credo che la creazione di questo stravagante xml personalizzato solo per una terza parte in una occasione debba essere definita qualcosa di generico come "XmlSerialize" in primo luogo.

Così, ho creato un secondo metodo che accetta un documento XML e prima, rimuove l'elemento di uno spazio dei nomi in questo modo:

xElement.Attributes().Where(a => a.IsNamespaceDeclaration && a.Value == "http://www.w3.org/2001/XMLSchema").Remove(); 

allora, scrive a XML con il codice di John. Infine restituisce che XML, dopo l'uscita da questo:

new XDeclaration("1.0", "Windows-1252", "yes").ToString() 

E questo è brutto, ma mi ottiene esattamente quello che mi serve per questa 3a parte per capire la mia XML.

+0

In realtà, utilizzare 'XmlReader.Create' e' XmlWriter.Create' invece di 'XmlTextReader' e' XmlTextWriter'. Inoltre, devi mettere queste cose in blocchi 'using'. –

+0

Alla fine sono andato con il tuo codice. Ma mi chiedo solo, fino a quando chiudo tutto, non è così buono come usare i blocchi? – Chris

+0

No. I blocchi 'using' assicurano che gli oggetti siano disposti, anche quando si verificano eccezioni. –

risposta

25

Prova questo:

public static string XmlSerialize(object o) 
{ 
    using (var stringWriter = new StringWriter()) 
    { 
     var settings = new XmlWriterSettings 
          { 
           Encoding = Encoding.GetEncoding(1252), 
           OmitXmlDeclaration = true 
          }; 
     using (var writer = XmlWriter.Create(stringWriter, settings)) 
     { 
      var xmlSerializer = new XmlSerializer(o.GetType()); 
      xmlSerializer.Serialize(writer, o); 
     } 
     return stringWriter.ToString(); 
    } 
} 

Questo non sbarazzarsi del xsd: namespace, ma poi, perché si vuole?


Aggiornamento: Sembra che ogni volta che si utilizza un StringWriter, si ottiene UTF-16, anche se si utilizza un XmlWriter su di esso con il set di codifica. Il prossimo passo sarebbe scrivere a MemoryStream. Ma ciò solleva la domanda sul perché si desidera restituire una stringa. Ad esempio, se hai intenzione di voltarti e di inviare la stringa a uno stream, dovremmo inviare direttamente a questo stream. Lo stesso vale per lo TextWriter.

+0

Sto usando un'API e hanno specificato che la cosa xsd non dovrebbe essere lì. Perché non lo vogliono e perché non riesco a ignorarlo, non ne ho idea. – Chris

+0

John, non voglio sbarazzarmi della dichiarazione xml. Voglio tenerlo e cambiare ciò che viene emesso. – Chris

+2

Sbarazzarsi di OmitXmlDeclaration = true, e si dovrebbe riavere la dichiarazione. Devi dare un calcio ai tuoi utenti dell'API ** veramente difficile ** se soffocano sulla dichiarazione xsd. Sarà necessario se xsi: tipo deve essere specificato. Se non seguiamo tutti gli standard, presto XML non sarà affatto standard. –

2

È possibile utilizzare uno XmlTextWriter anziché un StringWriter. Ecco un estratto di alcuni dei miei codici con il set di codifica.

XmlTextWriter textWriter = new XmlTextWriter(stream, Encoding.GetEncoding(1252)); 
textWriter.Namespaces = false; 
+3

'XmlTextWriter' non dovrebbe più essere utilizzato, a partire da .NET 2.0. –

0

FWIW, ho ottenuto il funzionamento della codifica utilizzando un XmlWriter con XMLWriterSettings. Ecco un esempio:

... 
// My object type was from a class generated by xsd. 
XmlSerializer xms = new XmlSerializer(typeof(SomeType)); 
SomeType objSt; 
using(FileStream fs = new FileStream("C:\SomeFile.xml", FileMode.Open, FileAccess.Read)) 
{  
    using(XmlReader xr = XmlReader.Create(fs)) // Supposed to preserve encoding. 
    { 
    objSt = (SomeType)xms.Deserialize(xr); 
    }  
} 

... 
... // Do some stuff, change some attribute values. 
... 

XmlWriterSettings xsw= new XmlWriterSettings(); 
xsw.Indent= true; 
xsw.NewLineOnAttributes= true; 
xsw.Encoding = Encoding.GetEncoding(1252); 
using(XmlWriter xwXsw = XmlWriter.Create("C:\SomeFile_Changed.xml",xsw)) 
{  
    xms.Serialize(xwXsw, objSt); 
} 
... 
... // Finish up and get out. 
... 

Per qualche ragione, sono stato in grado di ottenere tutto a funzionare una volta solo utilizzando l'oggetto XmlSerializer e serializzazione con un TextWriter, dal momento che secondo MS aiuto per XmlSerializer.Deserialize (XmlReader) " XmlReader rileva e utilizza automaticamente la codifica specificata dal documento XML. " Poi ho iniziato a giocare con XmlWriterSettings e ho rotto qualcosa ....

+0

Un ritardo di -1 per non aver inserito FileStream, 'XmlReader' e' XmlWriter' in blocchi '' using'. –

+0

Fresco - ma il commento afferma esplicitamente "senza gestione di eccezioni o" utilizzando "". Non sono sicuro del motivo per cui l'ho fatto in quel modo, tanto tempo fa. Non intendevo ferire i tuoi sentimenti :) – GTAE86

+0

A quale commento ti riferisci? –

Problemi correlati