XmlSerializer.Serialize BOM丢失

时间:2019-07-04 09:15:28

标签: c# xmlserializer

我正在使用以下代码存储我的课程:

FileStream stream = new FileStream(myPath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(myClass));
serializer.Serialize(stream, myClass);
stream.Close();

这会写一个文件,我可以用XmlSerializer.Deserialize来阅读。但是,生成的文件不是正确的文本文件。 XmlSerializer.Serialize不存储BOM表,但仍插入多字节字符。因此,它被隐式声明为ANSI文件(因为我们希望XML文件是文本文件,而没有BOM的文本文件在Windows中被视为ANSI),因此在某些编辑器中将ö表示为¶。

这是一个已知的错误吗?或我缺少的某些设置?

以下是生成的文件的开头:

<?xml version="1.0"?>
<SvnProjects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

文件中的第一个字节为十六进制3C,即<

2 个答案:

答案 0 :(得分:4)

是否具有BOM表不是“适当的文本文件”的定义。实际上,我想说的是,当今最典型的格式是没有BOM的UTF-8。我认为我从未看到有人在实际系统中实际使用过UTF-8 BOM!但是:如果您想要BOM,那很好:只需传入正确的Encoding;如果您想使用带有BOM的UTF-8:

using (var writer = XmlWriter.Create(myPath, s_settings))
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
    serializer.Serialize(writer, obj);
}

具有:

static readonly XmlWriterSettings s_settings =
    new XmlWriterSettings { Encoding = new UTF8Encoding(true) };

其结果是启动EF-BB-BF(UTF-8 BOM)的文件。

如果要使用不同编码,则只需将new UTF8Encoding替换为所需的内容,记住要启用BOM。

(注意:静态Encoding.UTF8实例已启用BOM,但是如果您专门打算使用BOM,则IMO最好在此处非常明确,就像您应该对{{1 }}您打算使用)


编辑:这里的主要区别是Encoding最终使用:

Serialize(Stream, object)

然后最终使用:

XmlTextWriter xmlWriter = new XmlTextWriter(stream, encoding: null) {
    Formatting = Formatting.Indented,
    Indentation = 2
};

所以:如果您使用的是API,则默认值为不带BOM的UTF-8。

答案 1 :(得分:1)

  1. 您必须将实例而不是类定义xml
  2. 要获取Unicode,必须声明 XmlWriter 或TextWriter
FileStream stream = new FileStream(myPath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(myClass));
XmlWriter writer = new XmlTextWriter(fs, Encoding.Unicode);
serializer.Serialize(writer, myClass);
stream.Close();