XDocument.ToString () rilascia il tag di codifica XML


103

C'è un modo per ottenere la codifica xml nella funzione toString ()?

Esempio:

xml.Save("myfile.xml");

porta a

<?xml version="1.0" encoding="utf-8"?>
<Cooperations>
  <Cooperation>
    <CooperationId>xxx</CooperationId>
    <CooperationName>Allianz Konzern</CooperationName>
    <LogicalCustomers>

Ma

tb_output.Text = xml.toString();

porta a un'uscita come questa

<Cooperations>
  <Cooperation>
    <CooperationId>xxx</CooperationId>
    <CooperationName>Allianz Konzern</CooperationName>
    <LogicalCustomers>
    ...

Risposte:


98

Scrivi esplicitamente la dichiarazione o usa StringWritere chiama Save():

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

class Test
{
    static void Main()
    {
        string xml = @"<?xml version='1.0' encoding='utf-8'?>
<Cooperations>
  <Cooperation />
</Cooperations>";

        XDocument doc = XDocument.Parse(xml);
        StringBuilder builder = new StringBuilder();
        using (TextWriter writer = new StringWriter(builder))
        {
            doc.Save(writer);
        }
        Console.WriteLine(builder);
    }
}

Potresti aggiungerlo facilmente come metodo di estensione:

public static string ToStringWithDeclaration(this XDocument doc)
{
    if (doc == null)
    {
        throw new ArgumentNullException("doc");
    }
    StringBuilder builder = new StringBuilder();
    using (TextWriter writer = new StringWriter(builder))
    {
        doc.Save(writer);
    }
    return builder.ToString();
}

Questo ha il vantaggio che non andrà a sbattere se non c'è una dichiarazione :)

Quindi puoi usare:

string x = doc.ToStringWithDeclaration();

Nota che userà utf-16 come codifica, perché questa è la codifica implicita in StringWriter. Puoi influenzarlo tu stesso creando una sottoclasse di StringWriter, ad esempio, per usare sempre UTF-8 .


14
Questo ha un piccolo problema in quanto la codifica nella dichiarazione XDocument viene ignorata e sostituita dalla codifica di StringWriter quando si effettua il salvataggio, che può essere o meno quello che si desidera
Sam Holder

2
Poi si combina il metodo di estensione con: Utf8StringWriter da stackoverflow.com/a/1564727/75963 ;)
Nick Josevski

12
Ho trovato più facile usare il metodo di estensione sopra ma restituire quanto segue ... return doc.Declaration + doc.ToString (); Se la dichiarazione è nulla, restituisce solo una stringa vuota.
Steve G.

Strano, ma non riesco a farlo funzionare ora ( .net fiddle ) - utilizza sempre la codifica "utf-16". Ho guardato dentro XDocument.Save(TextWriter)implementazione e semplicemente ignora la codifica della dichiarazione, al contrario di XDocument.Save(String)o XDocument.Save(Stream)implementazioni. Mi chiedo perché ...
Ilya Luzyanin

@ IlyaLuzyanin: Sì, userà "utf-16" come codifica quando passi a StringWriter, a meno che non ne usi uno che sovrascrive la Encodingproprietà. Ho un'altra risposta al riguardo. Pensavo stessi dicendo che stava abbandonando completamente la "codifica" ...
Jon Skeet

46

La proprietà Declaration conterrà la dichiarazione XML. Per ottenere il contenuto più la dichiarazione, puoi fare quanto segue:

tb_output.Text = xml.Declaration.ToString() + xml.ToString()

7
sembra che se non usi il nuovo XDeclaration ("1.0", "utf-8", "yes") nel tuo xdocument questo crei un errore perché xml.Declaration è nullo. Ma xml.save sembra rilevare automaticamente la codifica corretta.
Henrik P. Hessel

oppuretb_output.Text = @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + xml;
Bill Hoag

4
oppure... = $"{xdoc.Declaration}{Environment.NewLine}{xdoc}";
WernerCD

9

Usa questo:

output.Text = String.Concat(xml.Declaration.ToString() , xml.ToString())

2
Senza creare un nuovo XDeclaration ("1.0", "utf-8", "yes") e aggiungerlo in XDocument o altro oggetto, xml.Declaration.ToString () genererà un'eccezione nulla.
Ziggler

1
è più sicuro come di seguito perché Concat non si preoccupa delle stringhe null: output.Text = String.Concat (xml.Declaration, xml)
dmihailescu

3

Mi è piaciuto questo

        string distributorInfo = string.Empty;

        XDocument distributors = new XDocument();

     //below is important else distributors.Declaration.ToString() throws null exception
        distributors.Declaration = new XDeclaration("1.0", "utf-8", "yes"); 

        XElement rootElement = new XElement("Distributors");
        XElement distributor = null;
        XAttribute id = null;

        distributor = new XElement("Distributor");
        id = new XAttribute("Id", "12345678");
        distributor.Add(id);
        rootElement.Add(distributor);

        distributor = new XElement("Distributor");
        id = new XAttribute("Id", "22222222");

        distributor.Add(id);

        rootElement.Add(distributor);         

        distributors.Add(rootElement);

        distributorInfo = String.Concat(distributors.Declaration.ToString(), distributors.ToString());

Si prega di vedere sotto per quello che ottengo in distributoreInfo

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Distributors>
  <Distributor Id="12345678" />
  <Distributor Id="22222222" />
  <Distributor Id="11111111" />
</Distributors>

1
buon esempio. alcune note: 1) usa la nuova XDeclaration ("1.0", "utf-8") invece della nuova XDeclaration ("1.0", "utf-8", "yes"), 2) inserisci una nuova riga nell'ultima riga: distributors. Declaration.ToString () + Environment.NewLine + distributors.ToString ()
Alexey Obukhov

2

Simile alle altre risposte +1, ma un po 'più in dettaglio sulla dichiarazione e una concatenazione leggermente più accurata.

<xml />la dichiarazione dovrebbe essere su una propria riga in un XML formattato, quindi mi assicuro che sia stata aggiunta la nuova riga. NOTA: utilizzando Environment.Newlinecosì si produrrà la nuova riga specifica della piattaforma

// Parse xml declaration menthod
XDocument document1 =
  XDocument.Parse(@"<?xml version=""1.0"" encoding=""iso-8859-1""?><rss version=""2.0""></rss>");
string result1 =
  document1.Declaration.ToString() +
  Environment.NewLine +
  document1.ToString() ;

// Declare xml declaration method
XDocument document2 = 
  XDocument.Parse(@"<rss version=""2.0""></rss>");
document2.Declaration =
  new XDeclaration("1.0", "iso-8859-1", null);
string result2 =
  document2.Declaration.ToString() +
  Environment.NewLine +
  document2.ToString() ;

Entrambi i risultati producono:

<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0"></rss>

1

Alcune di queste risposte risolvono la richiesta del poster, ma sembrano eccessivamente complicate. Ecco un semplice metodo di estensione che evita la necessità di un writer separato, gestisce una dichiarazione mancante e supporta il parametro ToString SaveOptions standard.

public static string ToXmlString(this XDocument xdoc, SaveOptions options = SaveOptions.None)
{
    var newLine =  (options & SaveOptions.DisableFormatting) == SaveOptions.DisableFormatting ? "" : Environment.NewLine;
    return xdoc.Declaration == null ? xdoc.ToString(options) : xdoc.Declaration + newLine + xdoc.ToString(options);
}

Per utilizzare l'estensione, è sufficiente sostituire xml.ToString() conxml.ToXmlString()


0

Puoi anche usare un XmlWriter e chiamare il file

Writer.WriteDocType() 

metodo.


0
string uploadCode = "UploadCode";
string LabName = "LabName";
XElement root = new XElement("TestLabs");
foreach (var item in returnList)
{  
       root.Add(new XElement("TestLab",
                new XElement(uploadCode, item.UploadCode),
                new XElement(LabName, item.LabName)
                            )
               );
}

XDocument returnXML = new XDocument(new XDeclaration("1.0", "UTF-8","yes"),
             root);

string returnVal;
using (var sw = new MemoryStream())
{
       using (var strw = new StreamWriter(sw, System.Text.UTF8Encoding.UTF8))
       {
              returnXML.Save(strw);
              returnVal = System.Text.UTF8Encoding.UTF8.GetString(sw.ToArray());
       }
}

// ReturnVal has the string with XML data with XML declaration tag
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.