XDocument:将XML保存到没有BOM的文件

我正在使用XDocument生成一个utf-8 XML文件。

 XDocument xml_document = new XDocument( new XDeclaration("1.0", "utf-8", null), new XElement(ROOT_NAME, new XAttribute("note", note) ) ); ... xml_document.Save(@file_path); 

正确生成文件并使用xsd文件成功validation。

当我尝试将XML文件上传到在线服务时,该服务表明我的文件wrong at line 1wrong at line 1 ; 我发现问题是由文件的第一个字节上的BOM引起的。

你知道为什么将BOM附加到文件中,如何在没有它的情况下保存文件?

如字节顺序标记维基百科文章中所述:

虽然Unicode标准允许使用UTF-8的BOM, 但它不需要或推荐它 。 字节顺序在UTF-8中没有意义,因此BOM仅用于将文本流或文件标识为UTF-8或者是从具有BOM的另一种格式转换的

这是一个XDocument问题还是我应该联系在线服务提供商的人请求解析器升级?

使用XmlTextWriter并将其传递给XDocument的Save()方法,这样您就可以更好地控制所使用的编码类型:

 var doc = new XDocument( new XDeclaration("1.0", "utf-8", null), new XElement("root", new XAttribute("note", "boogers")) ); using (var writer = new XmlTextWriter(".\\boogers.xml", new UTF8Encoding(false))) { doc.Save(writer); } 

UTF8Encoding类构造函数具有一个重载,指定是否使用带有布尔值的BOM(字节顺序标记),在您的情况下为false

使用Notepad ++validation了此代码的结果,以检查文件的编码。

首先:服务提供商必须根据XML规范处理它,该规范声明在UTF-8表示的情况下可能存在BOM。

您可以强制保存XML而不使用BOM,如下所示:

 XmlWriterSettings settings = new XmlWriterSettings(); settings.Encoding = new UTF8Encoding(false); // The false means, do not emit the BOM. using (XmlWriter w = XmlWriter.Create("my.xml", settings)) { doc.Save(w); } 

(从这里用Google搜索: http : //social.msdn.microsoft.com/Forums/en/xmlandnetfx/thread/ccc08c65-01d7-43c6-adf3-1fc70fdb026a )

使用XDocument时摆脱BOM字符的最有效方法是只保存文档,然后直接将文件读取为文件,然后将其写回。 File例程将为您删除字符:

  XDocument xTasks = new XDocument(); XElement xRoot = new XElement("tasklist", new XAttribute("timestamp",lastUpdated), new XElement("lasttask",lastTask) ); ... xTasks.Add(xRoot); xTasks.Save("tasks.xml"); // read it straight in, write it straight back out. Done. string[] lines = File.ReadAllLines("tasks.xml"); File.WriteAllLines("tasks.xml",lines); 

(这很好,但是为了方便起见 – 至少你会有一个格式良好的文件上传到你的在线提供商);)