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

时间:2011-02-09 08:46:31

标签: c# linq-to-xml byte-order-mark

我正在使用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文件验证并成功。

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

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

Byte order mark维基百科文章中所述:

  

虽然Unicode标准允许使用BOM   UTF-8 它不需要或   推荐它。字节顺序没有   意思是UTF-8所以只有BOM   用于识别文本流或   文件为UTF-8或已转换   来自另一种具有BOM

的格式

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

4 个答案:

答案 0 :(得分:58)

使用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 ++验证了此代码的结果,以检查文件的编码。

答案 1 :(得分:26)

首先:服务提供商必须根据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

答案 2 :(得分:1)

使用 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);

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

答案 3 :(得分:0)

通过UTF-8文档

String XMLDec = xDoc.Declaration.ToString();
StringBuilder sb = new StringBuilder(XMLDec);
sb.Append(xDoc.ToString());
Encoding encoding = new UTF8Encoding(false); // false = without BOM
File.WriteAllText(outPath, sb.ToString(), encoding);