In the following code, I want to specify the encoding of XmlTextWriter to UTF8.
private string SerializeData()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.Indented;
writer.Settings.Encoding = Encoding.UTF8; // exception, writer.Settings is readonly
XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
serializer.Serialize(writer, anInstanceOfMyClass);
writer.Flush();
writer.Close();
return sb.ToString();
}
But the problem is XmlTextWriter.Settings is readonly. I can only specify the encoding in two otherconstructor overloads, XmlTextWriter(Stream, Encoding) and XmlTextWriter(String, Encoding). But I want to return an xml string and the constructor XmlTextWriter(TextWriter) does not have an Encoding parameter.
Is there other way to do that with the specific encoding
Thanks!

How to specify the encoding for XmlTextWriter?
Object01
DiscoFunk is right, the string is still UTF-16 encoded, but if you want to get greasy wit it, you could just skip calling the WriteStartDocument() method and write yer own.
eg.:
using(XmlWriter writer = XmlWriter.Create(obj))
{
writer.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");
writer.WriteStartElement("root");
writer.WriteStartElement("example_element");
writer.WriteEndElement();
writer.WriteEndElement();
writer.Flush();
}
Tada!
John Cramer
private string SerializeData()
{
StringBuilder sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; // why no effect
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(sb, settings))
{
XmlSerializer serializer =
new XmlSerializer(typeof(MyClass));
serializer.Serialize(writer, anInstanceOfMyClass);
writer.Flush();
writer.Close();
}
return sb.ToString();
}
But I still have a problem. Although I sepcifiy UTF8 encoding in the settings, and provide it to the Create method, the XML returned is still encoded in UTF16, as shown below.
< xml version="1.0" encoding="utf-16" >
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" GeneratedAt="2006-04-18 03:28:26">
...
My Windows regional setting is using Chinese. Is that the cause How could I mandate the XmlWriter to use UTF8 encoding
Thanks!
ommy
Martinro73
On my machine, the default encoding (Encoding.Default) is Chinese Simplified (GB2312), while
settings.Encoding is Unicode (UTF-8), but writer.Settings.Encoding is Unicode (UTF-16, I guess).
That means the static System.Xml.XmlWriter.Create(StringBuilder, XmlWriterSettings) method does not use the given settings to create the XmlWriter instance.
Is this a bug, or are there some reasons for the Create method to do that Maybe it is relevant with the environment, such as the Windows Regional and Language Options
Thanks!
Rasped
Just another idea....
Sending the XML output into a MemoryStream encoded as UTF-8 and then sending that into a string object really doesn't change anything except the text "utf-8". The end result is that your returned string is still UTF-16 encoded. Wouldn't it make more sense to create a UTF-16 encoded string then replace the UTF-16 with a UTF-8
xml.Replace("utf-16","utf-8");
Giles Knap
The following is the latest version. I use a StreamWriter (wrapped in an XmlWriter) to write to a MemoryStream, and then use a StreamReader to read the data out from the MemoryStream.
private string SerializeData()
{
string xml;
using (MemoryStream ms = new MemoryStream())
{
StreamWriter sw = new StreamWriter(ms);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
serializer.Serialize(writer, anInstanceOfMyClass);
writer.Flush();
writer.Close();
}
using (StreamReader sr = new StreamReader(ms))
{
ms.Position = 0;
xml = sr.ReadToEnd();
sr.Close();
}
}
return xml;
}
Is there a better way or any room for improvement
Thanks!