Bootstrap

XML 工具类

XML 工具类

1 通常情况下对象和XML可直接调用方法进行序列化。

public class XmlHelper
{
    /// <summary>
    /// XML转实体
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="strXML"></param>
    /// <returns></returns>
    public static T DESerializer<T>(string strXML) where T : class
    {
        try
        {
            using (StringReader sr = new StringReader(strXML))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                return serializer.Deserialize(sr) as T;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    /// <summary>
    /// 序列化XML
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string XmlSerialize<T>(T obj)
    {
        using (StringWriter sw = new StringWriter())
        {
            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            serializer.Serialize(sw, obj);
            sw.Close();
            return sw.ToString();
        }
    }

    /// <summary>
    /// 将对象序列化为 Xml文件
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="path">路径中要包含文件名,例如:D:/ReportInfo.xml</param>
    /// <typeparam name="T"></typeparam>
    public static void XmlSerializeFile<T>(T obj, string path)
    {

        XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
        namespaces.Add(string.Empty, string.Empty);
        try
        {
            using (StreamWriter writer = new StreamWriter(path))
            {
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                serializer.Serialize(writer, obj, namespaces);
                writer.Close();
            }

        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    ///  序列化XML
    ///  去除掉默认命名空间
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string XmlSerializeNONS<T>(T obj)
    {
        using (StringWriter sw = new StringWriter())
        {
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add(string.Empty, string.Empty);
            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            serializer.Serialize(sw, obj, namespaces);
            sw.Close();
            return sw.ToString();
        }
    }

    /// <summary>
    /// 序列化XML
    /// 去除 XML 声明 和 默认命名空间
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string XmlSerializeNoHeaderAndNS<T>(T obj)
    {
        string result = string.Empty;
        var encode = Encoding.UTF8;
        XmlWriterSettings setting = new XmlWriterSettings();
        setting.Encoding = encode;
        setting.OmitXmlDeclaration = true;
        XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
        namespaces.Add(string.Empty, string.Empty);
        using (MemoryStream output = new MemoryStream())
        {
            using (XmlWriter writer = XmlWriter.Create(output, setting))
            {
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                serializer.Serialize(writer, obj, namespaces);
                // 格式化XMl
                FormatXml(output);
                result = encode.GetString(output.ToArray());
                writer.Close();
            }
        }

        return result;
    }

    /// <summary>
    /// 格式化XMl
    /// </summary>
    /// <param name="memoryStream"></param>
    public static void FormatXml(MemoryStream memoryStream)
    {
        // 将MemoryStream中的数据读取到字符串
        memoryStream.Position = 0;
        StreamReader reader = new StreamReader(memoryStream);
        string xmlContent = reader.ReadToEnd();

        // 加载XML字符串到XDocument
        XDocument doc = XDocument.Parse(xmlContent);

        // 创建一个新的MemoryStream用于存储格式化后的XML
        MemoryStream formattedStream = new MemoryStream();

        // 使用XmlWriterSettings进行格式化设置
        XmlWriterSettings settings = new XmlWriterSettings();
        // 省略 XML 声明
        settings.OmitXmlDeclaration = true;
        settings.Indent = true; // 启用缩进
        settings.IndentChars = "    "; // 设置缩进字符
        settings.NewLineChars = "\r\n"; // 设置换行字符
        settings.NewLineHandling = NewLineHandling.Replace; // 在XML文本中使用设置的换行字符

        // 创建XmlWriter来写入格式化后的XML到新的MemoryStream
        using (XmlWriter writer = XmlWriter.Create(formattedStream, settings))
        {
            doc.WriteTo(writer);
            writer.Flush();
        }

        // 将格式化后的数据写回原MemoryStream
        memoryStream.SetLength(0); // 清空原MemoryStream
        formattedStream.Position = 0;
        formattedStream.CopyTo(memoryStream);

        // 关闭和释放资源
        formattedStream.Dispose();
        reader.Dispose();
    }


}

2 特殊情况

特殊类型通过下面的小案例来讲解,需要在类上加上注解

    /// <summary>
    /// 此时生成的XML标签为<Request></Request>
    /// </summary>
    [XmlRoot("Request")]
    public class ReportFilesRequest
    {
        public Header Header { get; set; } = new();

		// 对子标签自定义
        [XmlElement("Body")] 
        public ReportFilesBody ReportFilesBody { get; set; }
    }
	
	public class ReportFilesBody 
	{
		// 自定义集合类型
		// <Students>
		// 		<Student></Student>
		// 		<Student></Student>
		// <Students>
		[XmlArray("Students"), XmlArrayItem("Student")]
		public List<Student> Students{ get; set; } = new();
	}

最终生成的XML结构:

<Request>
    <Header></Header>
    <Body>
        <Students>
            <Student></Student>
            <Student></Student>
        </Students>
    </Body>
</Request>

3 补充:处理已有的XML数据

3.1 通过反序列化方法转化为对象进行处理(见工具类)

3.2 直接操作XML数据

		// 通过节点方式获取
		// 注意字符串要符合Xml数据规范
        string result = @"<Request>
	<Header>我是头部</Header>
	<Body>
		<Students>
			<Student>小王</Student>
			<Student>小宋</Student>
			<Student></Student>
		</Students>
	</Body>
</Request>";

        // 处理返回结果
        XDocument doc = XDocument.Parse(result);
        // 取出标签中的值
        var header = doc.Descendants("Header").FirstOrDefault()?.Value;
        var student = doc.Descendants("Student").FirstOrDefault()?.Value;
        // 返回标签
        var body = doc.Descendants("Body").FirstOrDefault();
        Console.WriteLine(header);
        Console.WriteLine(student);
        Console.WriteLine(body);

控制台输出结果:

我是头部
小王
<Body>
  <Students>
    <Student>小王</Student>
    <Student>小宋</Student>
    <Student></Student>
  </Students>
</Body>
;