Pokud máme XML dokument v objektu XElement nebo XDocument a převedeme ho do textové reprezentace pomoci metody ToString(), není do výpisu zahrnuta hlavička xml dokumentu:
static void Main()
{
XElement xml = XElement.Parse("<Root><Child></Child></Root>");
Console.WriteLine(xml.ToString());
}
<Root>
<Child></Child>
</Root>
Pokud ale chceme dokument převést na string včetně hlavičky xml dokumentu, nejspíše nás napadne použít metodu Save() a jako výstup třídu StringWriter:
static void Main()
{
XElement xml = XElement.Parse("<Root><Child></Child></Root>");
var sb = new System.Text.StringBuilder();
using (var writer = new StringWriter(sb))
{
xml.Save(writer);
}
Console.WriteLine(sb.ToString());
}
<?xml version="1.0" encoding="utf-16"?>
<Root>
<Child></Child>
</Root>
Jak je vidět, v tomto případě dokument již obsahuje xml hlavičku, ale se specifikaci kódování (encoding) UTF16. Důvodem je to, že při vytváření hlavičky dokumentu se XLINQ “kouká” na vlastnost Encoding výstupního objektu StringWriter a ten vždy vrací kódování UTF16.
To by nám mohlo vadit v případě, kdy by byl vytvořený řetězec později (například se bude přenášet na klienta pomoci WCF služby) ukládán do textového souboru s kódováním jiným, zpravidla ve výchozím UTF8.
Jak tedy zařídit, aby byla již do obsahu řetězce zapsána informace o jiném kódování? Řešení je poměrně jednoduché a spočívá v podědění třídy StringWriter, ve které pak vlastnost Encoding přepíšeme:
internal sealed class StringWriterWithEncoding : StringWriter
{
#region member varible and default property initialization
private System.Text.Encoding encoding;
#endregion
#region constructors and destructors
public StringWriterWithEncoding(System.Text.Encoding encoding)
{
this.encoding = encoding;
}
public StringWriterWithEncoding(System.Text.StringBuilder builder, System.Text.Encoding encoding)
: base(builder)
{
this.encoding = encoding;
}
#endregion
#region property getters/setters
public override System.Text.Encoding Encoding
{
get { return encoding; }
}
#endregion
}
S využitím této pomocné třídy již můžeme při exportu xml dokumentu snadno určit jaké kódování má být do hlavičky dokumentu zapsáno:
static void Main()
{
XElement xml = XElement.Parse("<Root><Child></Child></Root>");
var sb = new System.Text.StringBuilder();
using (var writer = new StringWriterWithEncoding(sb, System.Text.Encoding.UTF8))
{
xml.Save(writer);
}
Console.WriteLine(sb.ToString());
}
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Child></Child>
</Root>