C# NetCore XML 反序列化解析错误:<xml xmlns=‘‘> was not expected 及 Encoding=utf-16问题
xml帮助类在最后
刚好有业务需要解析xml文件,于是找到帮助类代码开始尝试解析文件,总是出现异常:<xml xmlns='xxxxxxxxxxxxxxxx'> was not expected,开始寻找解决方案:
要使结果正确,必须满足两个条件中的任意一个: 1. TResult 类的类名称和 XML 根元素名一致。 2. 若类名和根元素名称不一致,在初始化 XmlSerializer 时传入第二个参数,new XmlRootAttribute("【根元素名称】"),以指定根元素名称
否则 Xmlserializer.Deserialize 抛出如下异常:
System.InvalidOperationException: There is an error in XML document (1, 2). ---> System.InvalidOperationException: <xml xmlns=''> was not expected.
Result StackTrace:
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderTResult.Read3_RootElementName()
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(TextReader textReader)
其实我的文件根节点与实体是一致的,添加 XmlRoot依然报错,继续找问题原因,各种调试后发现可能是xmlns命名空间不在xml规范内,于是指定命名空间:
果然反序列化成功了 。
还有一个就是xml写入指定目录,于是开始按规则创建xml文件,实体创建后,使用SerializeObject序列化结果如下图:
正常应该是utf8,怎么出现utf16呢?经测试后发现原来是使用的StringWriter的问题,因此,提醒诸位,如果使用非Stream类的输出,如StringBuilder/StringWriter,作为XmlWriter输出的话,请注意你的xml的Encoding。
查看StringWriter发现了Encoding
于是重写StringWriter的Encoding:
/// <summary>
/// hef 2023.04.20 08:37 新建StringUTF8Writer类改写Encoding
/// StringWriter默认encoding="utf-16"改写为Encoding.UTF8
/// </summary>
public class StringUTF8Writer : System.IO.StringWriter
{public override Encoding Encoding{get { return Encoding.UTF8; }}
}
至此,序列化xml文件内容成功。
全部代码如下:
/// <summary>/// hef 2023.04.19 15:36 新建xml序列化帮助类/// </summary>public class XmlSerializeHelper{/// <summary>/// 序列化/// </summary>/// <param name="TValue">要序列化的对象</param>/// <returns></returns>static public string SerializeObject(object TValue){if (TValue is null){return null;}try{XmlSerializer xmlSerializer = new XmlSerializer(TValue.GetType());//using (StringWriter stringWriter = new StringWriter())using (StringUTF8Writer stringWriter = new StringUTF8Writer()){using (XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter){Formatting = Formatting.Indented,Namespaces = false}){xmlSerializer.Serialize(stringWriter, TValue);return stringWriter.ToString();}}}catch (Exception exception){throw exception;}}/// <summary>/// 反序列化/// </summary>/// <typeparam name="T">要序列化的对象</typeparam>/// <param name="value">文件内容</param>/// <returns></returns>static public T DeserializeObject<T>(string value) where T : class, new(){if (string.IsNullOrWhiteSpace(value)){return null;}try{XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));using (TextReader textReader = new StringReader(value)){T t = new T();t = (T)xmlSerializer.Deserialize(textReader);return t;}}catch (Exception exception){throw exception;}}}/// <summary>/// hef 2023.04.20 08:37 新建StringUTF8Writer类改写Encoding/// StringWriter默认encoding="utf-16"改写为Encoding.UTF8/// </summary>public class StringUTF8Writer : System.IO.StringWriter{public override Encoding Encoding{get { return Encoding.UTF8; }}}