27 Stimmen

Beim Speichern eines XmlDocuments wird die Kodierung in der XmlDeclaration (UTF8) ignoriert und UTF16 verwendet.

Ich habe den folgenden Code:

var doc = new XmlDocument();

XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(xmlDeclaration);

XmlElement root = doc.CreateElement("myRoot");
doc.AppendChild(root);
root.InnerText = "myInnerText";

StringWriter sw = new StringWriter();
doc.Save(sw);
Console.WriteLine(sw.ToString());

Console.WriteLine();

MemoryStream ms = new MemoryStream();
doc.Save(ms);
Console.WriteLine(Encoding.ASCII.GetString(ms.ToArray()));

Und hier ist das Ergebnis:

<?xml version="1.0" encoding="utf-16"?>
<myRoot>myInnerText</myRoot>

???<?xml version="1.0" encoding="UTF-8"?>
<myRoot>myInnerText</myRoot>

Im Grunde genommen wird eine Xml-Datei erstellt und die Kodierung auf utf8 gesetzt, aber beim Speichern in stringwriter wird die Kodierung ignoriert und utf16 verwendet. Bei der Verwendung eines Speicherstroms wird jedoch utf8 (mit den zusätzlichen BOM-Zeichen) verwendet.

Warum ist das so? Warum wird meine explizite Kodierungseinstellung von utf-8 nicht beachtet?

Herzlichen Dank!

0 Stimmen

Nur neugierig, haben Sie versuchen, geben null/string.empty in der Codierung und sehen?

0 Stimmen

Wenn ich das tue, ist der Stringwriter immer noch utf16, und der Memorystream hat keine Kodierung in seiner Deklaration.

0 Stimmen

Es sieht z.B. so aus: <?xml version="1.0"?>

35voto

vcsjones Punkte 134300

Da Sie nur ein XML-Element setzen, das UTF-8 angibt, speichern Sie es nicht wirklich als UTF-8. Sie müssen den Ausgabestrom auf die Verwendung von UTF-8 einstellen, etwa so:

var doc = new XmlDocument();
XmlElement root = doc.CreateElement("myRoot");
doc.AppendChild(root);
root.InnerText = "myInnerText";
using(TextWriter sw = new StreamWriter("C:\\output.txt", false, Encoding.UTF8)) //Set encoding
{
    doc.Save(sw);
}

Wenn Sie das getan haben, müssen Sie nicht einmal die XML-Deklaration hinzufügen. Das Programm findet es selbst heraus. Wenn Sie es in einem MemoryStream speichern möchten, verwenden Sie einen StreamWriter, der den MemoryStream umhüllt.

1 Stimmen

Ok, das macht jetzt Sinn. Danke

0 Stimmen

Der Xml-Writer überschreibt also alles, was Sie in die Xml-Deklaration eingeben, je nachdem, was er speichert, sei es ein Stream, ein Textwriter oder eine Datei.

0 Stimmen

Die XML-Deklaration ist einfach ein Element (wenn auch ein seltsames), soweit sie betroffen ist. Sie gibt an, wie sie gespeichert wird, nicht wie sie gespeichert werden soll. Deshalb wird es beim Speichern für Sie dort abgelegt.

8voto

djunod Punkte 4678

Ich verwende die folgende Methode, sie schreibt es schön aus y als UTF-8

public static string Beautify(XmlDocument doc)
{
    string xmlString = null;
    using (MemoryStream ms = new MemoryStream()) {
        XmlWriterSettings settings = new XmlWriterSettings {
            Encoding = new UTF8Encoding(false),
            Indent = true,
            IndentChars = "  ",
            NewLineChars = "\r\n",
            NewLineHandling = NewLineHandling.Replace
        };
        using (XmlWriter writer = XmlWriter.Create(ms, settings)) {
            doc.Save(writer);
        }
        xmlString = Encoding.UTF8.GetString(ms.ToArray());
    }
    return xmlString;
}

Nennen Sie es so:

File.WriteAllText(fileName, Utilities.Beautify(xmlDocument));

2voto

Pace Punkte 38003

De die MSDN können wir sehen...

Die Kodierung des TextWriters bestimmt die Kodierung, die ausgegeben wird (die Kodierung des Knotens XmlDeclaration wird durch die Kodierung des TextWriters ersetzt). Wurde am TextWriter keine Kodierung angegeben, wird das XmlDokument ohne Kodierungsattribut gespeichert.

Wenn Sie die Kodierung aus der XmlDeclaration verwenden möchten, müssen Sie einen Stream verwenden, um das Dokument zu speichern.

0 Stimmen

Also im Grunde sagen Sie, dass C# die xmldeclaration ignoriert, wenn das Dokument in einem Textwriter speichern?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X