My first few attempts involved streams, byte arrays and many encoding issues. Turns out that strings in .NET are already UTF-16, so only the xml declaration needs to be changed.
The answer is actually quite simple. Here's an extension method that loads the string into an XmlDocument, changes the declaration, and grabs the OuterXml.
public static class XmlDocumentExtensions
{
public static string ToEncoding(this XmlDocument document, Encoding encoding)
{
if (document.FirstChild.NodeType == XmlNodeType.XmlDeclaration)
{
XmlDeclaration xmlDeclaration = (XmlDeclaration)document.FirstChild;
if (String.Compare(xmlDeclaration.Encoding, encoding.WebName, StringComparison.OrdinalIgnoreCase) != 0)
{
xmlDeclaration.Encoding = encoding.WebName;
return document.OuterXml;
}
}
return document.OuterXml;
}
}
You can use it like so:
XmlDocument document = new XmlDocument();
document.LoadXml(xml);
xml = document.ToEncoding(Encoding.Unicode);