XDocument.ToString () suelta la etiqueta de codificación XML


103

¿Hay alguna forma de obtener la codificación xml en la función toString ()?

Ejemplo:

xml.Save("myfile.xml");

lleva a

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

Pero

tb_output.Text = xml.toString();

conduce a una salida como esta

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

Respuestas:


98

O escriba explícitamente la declaración o use un StringWritery llame 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);
    }
}

Puede agregarlo fácilmente como un método de extensión:

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();
}

Esto tiene la ventaja de que no explotará si no hay una declaración :)

Entonces puedes usar:

string x = doc.ToStringWithDeclaration();

Tenga en cuenta que usará utf-16 como codificación, porque esa es la codificación implícita en StringWriter. Sin embargo, puede influir en eso creando una subclase de StringWriter, por ejemplo, para usar siempre UTF-8 .


14
Esto tiene un pequeño problema, ya que la codificación en la declaración de XDocument se ignora y se reemplaza por la codificación de StringWriter al guardar, que puede ser o no lo que desea
Sam Holder

2
Luego, combina el método de extensión con: Utf8StringWriter de stackoverflow.com/a/1564727/75963 ;)
Nick Josevski

12
Me resultó más fácil usar el método de extensión anterior, pero devuelve lo siguiente ... return doc.Declaration + doc.ToString (); Si la Declaración es nula, solo da como resultado una cadena vacía.
Steve G.

Extraño, pero no puedo hacerlo funcionar ahora ( .net violín ) - siempre usa codificación "utf-16". He mirado en el interior de XDocument.Save(TextWriter)la aplicación y simplemente ignora la codificación de la declaración, en lugar de XDocument.Save(String)o XDocument.Save(Stream)implementaciones. Me pregunto por qué ...
Ilya Luzyanin

@IlyaLuzyanin: Sí, usará "utf-16" como codificación cuando pase un StringWriter, a menos que use uno que anule la Encodingpropiedad. Tengo otra respuesta sobre eso. Pensé que estabas diciendo que estaba eliminando la "codificación" por completo ...
Jon Skeet

46

La propiedad de declaración contendrá la declaración XML. Para obtener el contenido más la declaración, puede hacer lo siguiente:

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

7
parece que si no usa el nuevo XDeclaration ("1.0", "utf-8", "yes") en su xdocument, esto crea un error porque xml.Declaration es nulo. Pero xml.save parece detectar automáticamente la codificación correcta.
Henrik P. Hessel

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

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

9

utilizar este:

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

2
Sin crear un nuevo XDeclaration ("1.0", "utf-8", "yes") y agregarlo a XDocument u otro objeto, xml.Declaration.ToString () arrojará una excepción nula.
Ziggler

1
es más seguro como a continuación porque a Concat no le importan las cadenas nulas: output.Text = String.Concat (xml.Declaration, xml)
dmihailescu

3

Me gustó esto

        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());

Por favor vea a continuación lo que obtengo en distributorInfo

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

1
buen ejemplo. algunas notas: 1) use new XDeclaration ("1.0", "utf-8") en lugar de new XDeclaration ("1.0", "utf-8", "yes"), 2) inserte una nueva línea en la última línea: distributors. Declaration.ToString () + Environment.NewLine + distributors.ToString ()
Alexey Obukhov

2

Similar a las otras respuestas +1, pero un poco más de detalle sobre la declaración y una concatenación un poco más precisa.

<xml />La declaración debe estar en su propia línea en un XML formateado, así que me aseguro de que agreguemos la nueva línea. NOTA: usarlo Environment.Newlineproducirá la nueva línea específica de la plataforma

// 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() ;

Ambos resultados producen:

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

1

Algunas de estas respuestas resuelven la solicitud del cartel, pero parecen demasiado complicadas. Este es un método de extensión simple que evita la necesidad de un escritor separado, maneja una declaración faltante y es compatible con el parámetro estándar ToString SaveOptions.

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);
}

Para usar la extensión, simplemente reemplácela xml.ToString()conxml.ToXmlString()


0

También puede usar un XmlWriter y llamar al

Writer.WriteDocType() 

método.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.