背景


最近在做博客的SEO,在 Google Search Console提交 Sitemap的时候提示格式不正确,但是Bing WebMaster Tool又能接受,对比了下Google提供的格式发现我的 Sitemap的xml文件头中编码部分是 encoding=utf-16但是标准 Sitemaputf-8的,微软估计做了兼容所以没有报错

原因


本博的 Sitemap是使用 StringBuilderXmlWriter构建的,

var sb =new StringBuilder();
var writerSettings = new XmlWriterSettings { Indent = true,Encoding = Encoding.UTF8};
using (XmlWriter writer = XmlWriter.Create(sb, writerSettings))
{
    ...
}

但是使用 StringBuilder 创建XmlWriter时会忽略XmlWriterSettings中的编码格式,而使用StringbuilderUTF-16编码(C# 中的字符串在内存中始终以 UTF-16 编码存储),导致输出的xml文件头encoding="utf-16"

解决方案


可以使用MemoryStream配合StreamWriter创建XmlWriter来解决

using var mem =new MemoryStream();
using var sw = new StreamWriter(mem, Encoding.UTF8);
var writerSettings = new XmlWriterSettings { Indent = true,Encoding = Encoding.UTF8};
using (XmlWriter writer = XmlWriter.Create(sw, writerSettings))
{
    writer.WriteStartDocument();
    writer.WriteStartElement("Root");
    writer.WriteElementString("Child", "Hello, World!");
    writer.WriteEndElement();
    writer.WriteEndDocument();
}
Console.WriteLine(Encoding.UTF8.GetString(mem.ToArray()));

此时xml文件头中encoding="utf-8"