C# XML序列化与反序列化记录
简介与实现
.NET提供了很不错的XML序列化/反序列化器
所在命名空间:System.Xml.Serialization
- 封装实现代码
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Xml.Serialization;
namespace Unified.Services.Core
{
public class XmlSerializerHelper
{
/// <summary>
/// 将XML序列化为实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xmlObj"></param>
/// <returns></returns>
public static T DeserializeXML<T>(string xmlObj)
{
XmlSerializer serializer = new XmlSerializer(typeof(T),new XmlRootAttribute("response"));
using (StringReader reader = new StringReader(xmlObj))
{
return (T)serializer.Deserialize(reader);
}
}
/// <summary>
/// 将对象序列化为xml
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string SerializeXml(object data)
{
using (StringWriter sw = new StringWriter())
{
XmlSerializer xz = new XmlSerializer(data.GetType());
xz.Serialize(sw, data);
XElement xmlDocumentWithoutNs = RemoveAllNamespaces(XElement.Parse(sw.ToString()));
return xmlDocumentWithoutNs.ToString();
}
}
/// <summary>
/// 删除命名空间
/// </summary>
/// <param name="xmlDocument"></param>
/// <returns></returns>
private static XElement RemoveAllNamespaces(XElement xmlDocument)
{
if (!xmlDocument.HasElements)
{
XElement xElement = new XElement(xmlDocument.Name.LocalName);
xElement.Value = xmlDocument.Value;
foreach (XAttribute attribute in xmlDocument.Attributes())
xElement.Add(attribute);
return xElement;
}
return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
}
}
}
注意事项
xml 字符串验证
/// <summary>
/// Xml字符串格式验证
/// </summary>
/// <param name="xmlString">Xml字符串</param>
/// <returns></returns>
public static bool IsValidXml(string xmlString)
{
try
{
// 创建XmlDocument对象,加载xml字符串
new XmlDocument().LoadXml(xmlString);
// 如果没有异常,则说明xml字符串是有效的
return true;
}
catch (XmlException ex)
{
// 如果有异常,则说明xml字符串是无效的
return false;
}
}
实体序列化为 xml
序列化集合的时候不要“再包一层”
[XmlRoot("department")]
public class Department {
public string DeptName { get; set; };
[XmlElement("Employee")]
public List<Employee> Details { get; set; };
}
xml序列化与json序列化不一样,顶级标签名是当前实体的 Class Name 所以需要进行特性标注[XmlRoot(“elementName”)],标注之后当前类的 Class Name 就成了序列化之后xml的顶级标签名。
List 集合类型序列化也同意需要进行标注,如上。
双标签序列化
这里的 “双标签” ,是指当属性为 null 时 默认序列化当前标签为单标签,很多时候我们需要的是 Value 为空时标签也是双标签。当然上述实现代码就是,属性为 null 时也是双标签。
删除命名空间
xml 序列化之后默认会有类似下面这种,带有 namespace 的内容
<department xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- blah blah blah -->
</department>
实现代码中的
RemoveAllNamespaces()
方法就是用来删除 namespace 的
xml 序列化为实体
xml 序列化为实体需要注意的是顶级标签 XmlRootAttribute(“elementName”) 这里默认是添加了指定顶级标签名的