XDocument.ToString () löscht das XML-Codierungs-Tag


103

Gibt es eine Möglichkeit, die XML-Codierung in der Funktion toString () abzurufen?

Beispiel:

xml.Save("myfile.xml");

führt zu

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

Aber

tb_output.Text = xml.toString();

führt zu einer solchen Ausgabe

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

Antworten:


98

Schreiben Sie die Deklaration entweder explizit aus oder verwenden Sie a StringWriterund call 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);
    }
}

Sie können dies leicht als Erweiterungsmethode hinzufügen:

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

Dies hat den Vorteil, dass es nicht knallt, wenn es keine Erklärung gibt :)

Dann können Sie verwenden:

string x = doc.ToStringWithDeclaration();

Beachten Sie, dass dabei utf-16 als Codierung verwendet wird, da dies die implizite Codierung in ist StringWriter. Sie können dies jedoch selbst beeinflussen, indem Sie eine Unterklasse von erstellen StringWriter, z. B. um immer UTF-8 zu verwenden .


14
Dies hat ein kleines Problem, da die Codierung in der XDocument-Deklaration ignoriert und beim Speichern durch die Codierung des StringWriter ersetzt wird, was möglicherweise das ist, was Sie wollen
Sam Holder,

2
Dann kombinieren Sie die Erweiterungsmethode mit: Utf8StringWriter von stackoverflow.com/a/1564727/75963 ;)
Nick Josevski

12
Fand es einfacher, die obige Erweiterungsmethode zu verwenden, gab aber Folgendes zurück ... return doc.Declaration + doc.ToString (); Wenn die Deklaration null ist, führt dies nur zu einer leeren Zeichenfolge.
Steve G.

Seltsam, aber ich kann es jetzt nicht zum Laufen bringen ( .net-Geige ) - es verwendet immer die "utf-16" -Codierung. Ich habe mir die XDocument.Save(TextWriter)Implementierung angesehen und sie ignoriert nur die Codierung der Deklaration im Gegensatz zu XDocument.Save(String)oder XDocument.Save(Stream)Implementierungen. Ich frage mich warum ...
Ilya Luzyanin

@IlyaLuzyanin: Ja, es wird "utf-16" als Codierung verwendet, wenn Sie a übergeben StringWriter, es sei denn, Sie verwenden eine, die die EncodingEigenschaft überschreibt . Ich habe noch eine Antwort darauf. Ich dachte, Sie sagten, es würde die "Codierung" vollständig
löschen

46

Die Declaration-Eigenschaft enthält die XML-Deklaration. Um den Inhalt plus Deklaration zu erhalten, können Sie Folgendes tun:

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

7
Wenn Sie in Ihrem xdocument keine neue XDeclaration ("1.0", "utf-8", "yes") verwenden, wird anscheinend ein Fehler erstellt, da xml.Declaration null ist. Aber xml.save scheint die richtige Codierung automatisch zu erkennen.
Henrik P. Hessel

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

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

9

benutze das:

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

2
Ohne eine neue XDeclaration ("1.0", "utf-8", "yes") zu erstellen und in XDocument oder ein anderes Objekt hinzuzufügen, löst xml.Declaration.ToString () eine Null-Ausnahme aus.
Ziggler

1
Es ist sicherer wie unten, weil Concat sich nicht um Null-Strings kümmert: output.Text = String.Concat (xml.Declaration, xml)
dmihailescu

3

Das hat mir gefallen

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

Bitte sehen Sie unten, was ich in DistributorInfo bekomme

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

1
gutes Beispiel. Einige Hinweise: 1) Verwenden Sie eine neue XDeclaration ("1.0", "utf-8") anstelle einer neuen XDeclaration ("1.0", "utf-8", "yes"). 2) Fügen Sie eine neue Zeile in die letzte Zeile ein: Verteiler. Declaration.ToString () + Environment.NewLine + Distributoren.ToString ()
Alexey Obukhov

2

Ähnlich wie bei den anderen +1 Antworten, jedoch etwas detaillierter über die Deklaration und eine etwas genauere Verkettung.

<xml />Die Deklaration sollte in einem formatierten XML in einer eigenen Zeile stehen, daher stelle ich sicher, dass die neue Zeile hinzugefügt wurde. HINWEIS: Environment.NewlineWenn Sie dies verwenden, wird die plattformspezifische Newline erstellt

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

Beide Ergebnisse ergeben:

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

1

Einige dieser Antworten lösen die Anfrage des Posters, scheinen jedoch zu kompliziert zu sein. Hier ist eine einfache Erweiterungsmethode, die die Notwendigkeit eines separaten Writers vermeidet, eine fehlende Deklaration behandelt und den Standardparameter ToString SaveOptions unterstützt.

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

Um die Erweiterung zu verwenden, ersetzen Sie einfach xml.ToString()mitxml.ToXmlString()


0

Sie können auch einen XmlWriter verwenden und den aufrufen

Writer.WriteDocType() 

Methode.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.