2011-02-09 12 views
22

Sto generando un file utf-8 XML utilizzando XDocument.XDocument: salvataggio XML in un file senza BOM

XDocument xml_document = new XDocument(
        new XDeclaration("1.0", "utf-8", null), 
        new XElement(ROOT_NAME,      
        new XAttribute("note", note) 
       ) 
      ); 
... 
xml_document.Save(@file_path); 

Il file viene generato correttamente e convalidato con un file xsd con esito positivo.

Quando si tenta di caricare il file XML su un servizio in linea, il servizio indica che il mio file è wrong at line 1; Ho scoperto che il problema è causato dalla distinta base sui primi byte del file.

Sapete perché il BOM viene aggiunto al file e come posso salvare il file senza di esso?

Come indicato nel Byte order mark Articolo Wikipedia:

Mentre standard Unicode permette BOM in UTF-8 non richiede o consiglio. l'ordine dei byte non ha significato in UTF-8 in modo da una distinta solo serve per identificare un flusso di testo o file come UTF-8 o che è stato convertito da un altro formato che ha una distinta

È un XDocument problema o dovrei contattare i ragazzi del fornitore di servizi online per chiedere un aggiornamento del parser?

risposta

47

Utilizzare un XmlTextWriter e passa che al di XDocument Save() il metodo, in questo modo si può avere più controllo sul tipo di codifica utilizzata:

var doc = new XDocument(
    new XDeclaration("1.0", "utf-8", null), 
    new XElement("root", new XAttribute("note", "boogers")) 
); 
using (var writer = new XmlTextWriter(".\\boogers.xml", new UTF8Encoding(false))) 
{ 
    doc.Save(writer); 
} 

La classe costruttore UTF8Encoding ha un sovraccarico che specifica se o non utilizzare il BOM (Byte Order Mark) con un valore booleano, nel tuo caso false.

Il risultato di questo codice è stato verificato utilizzando Notepad ++ per ispezionare la codifica del file.

+0

Quando lo apri con Notepad ++ è ancora in utf-8 anche usando 'new UTF8Encoding (false)'? – systempuntoout

+0

Pensavo volessi farlo in UTF-8, solo senza il BOM? –

+0

sì, è corretto. Stavo solo chiedendo se 'new UTF8Encoding (false)' potrebbe avere qualche altra implicazione. – systempuntoout

23

Prima di tutto: il provider di servizi DEVE gestirlo, in base alle specifiche XML, in base al quale la distinta base potrebbe essere presente in caso di rappresentazione UTF-8.

È possibile forzare per salvare il XML senza BOM come questo:

XmlWriterSettings settings = new XmlWriterSettings(); 
settings.Encoding = new UTF8Encoding(false); // The false means, do not emit the BOM. 
using (XmlWriter w = XmlWriter.Create("my.xml", settings)) 
{ 
    doc.Save(w); 
} 

(Googled da qui: http://social.msdn.microsoft.com/Forums/en/xmlandnetfx/thread/ccc08c65-01d7-43c6-adf3-1fc70fdb026a)

+0

* La distinta base potrebbe essere presente in caso di rappresentazione UTF-8 * puoi indicarmi questo specifico documento? – systempuntoout

+1

Ecco qui: http://www.w3.org/TR/2006/REC-xml-20060816/#charencoding Primo paragrafo: "Tutti i processori XML DEVONO essere in grado di leggere entità sia in UTF-8 che in UTF-16 codifiche ". La codifica UTF-8 abilita (anche se non richiede) BOM (vedi il commento di Joe sotto), quindi i processori XML devono essere in grado di elaborare file UTF-8 con BOM. –

+2

"Mentre lo standard Unicode consente BOM in UTF-8, non lo richiede o lo consiglia. L'ordine byte non ha significato in UTF-8" - http://en.wikipedia.org/wiki/Byte_order_mark –

2

Il modo più opportuno per sbarazzarsi del carattere BOM quando si utilizza XDocument è solo salvare il documento, quindi fare un file dritto leggere come un file, quindi riscriverlo. Le routine di file metteranno a nudo il carattere per voi:

 XDocument xTasks = new XDocument(); 
     XElement xRoot = new XElement("tasklist", 
      new XAttribute("timestamp",lastUpdated), 
      new XElement("lasttask",lastTask) 
     ); 
     ... 
     xTasks.Add(xRoot); 
     xTasks.Save("tasks.xml"); 

     // read it straight in, write it straight back out. Done. 
     string[] lines = File.ReadAllLines("tasks.xml"); 
     File.WriteAllLines("tasks.xml",lines); 

(E 'Hoky, ma funziona per il bene della convenienza - almeno avrete un file in formato corretto per caricare il tuo fornitore online);)

+3

ben spiegato per il tuo primo postino :) – Amar

+0

Bello! L'ho usato perché non volevo perdere la formazione. – conor

Problemi correlati