C#XmlHelper帮助类操作Xml文档的通用方法汇总
前言
该篇文章主要总结的是自己平时工作中使用频率比较高的Xml文档操作的一些常用方法和收集网上写的比较好的一些通用Xml文档操作的方法(主要包括Xml序列化和反序列化,Xml文件读取,Xml文档节点内容增删改的一些通过方法)。当然可能还有很多方法会漏了,假如各位同学好的方法可以在文末留言,我会统一收集起来。
C#XML基础入门
Xml反序列化为对象
#region Xml反序列化为对象 /// <summary>
/// Xml反序列化为指定模型对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="xmlContent">Xml内容</param>
/// <param name="isThrowException">是否抛出异常</param>
/// <returns></returns>
public static T XmlConvertToModel<T>(string xmlContent, bool isThrowException = false) where T : class
{
StringReader stringReader = null;
try
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
stringReader = new StringReader(xmlContent);
return (T)xmlSerializer.Deserialize(stringReader);
}
catch (Exception ex)
{
if (isThrowException)
{
throw ex;
}
return null;
}
finally
{
stringReader?.Dispose();
}
} /// <summary>
/// 读取Xml文件内容反序列化为指定的对象
/// </summary>
/// <param name="filePath">Xml文件的位置(绝对路径)</param>
/// <returns></returns>
public static T DeserializeFromXml<T>(string filePath)
{
try
{
if (!File.Exists(filePath))
throw new ArgumentNullException(filePath + " not Exists");
using (StreamReader reader = new StreamReader(filePath))
{
XmlSerializer xs = new XmlSerializer(typeof(T));
T ret = (T)xs.Deserialize(reader);
return ret;
}
}
catch (Exception ex)
{
return default(T);
}
} #endregion
对象序列化为Xml
#region 对象序列化为Xml /// <summary>
/// 对象序列化为Xml
/// </summary>
/// <param name="obj">对象</param>
/// <param name="isThrowException">是否抛出异常</param>
/// <returns></returns>
public static string ObjectSerializerXml<T>(T obj, bool isThrowException = false)
{
if (obj == null)
{
return string.Empty;
} try
{
using (StringWriter sw = new StringWriter())
{
Type t = obj.GetType();
//强制指定命名空间,覆盖默认的命名空间
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
//在Xml序列化时去除默认命名空间xmlns:xsd和xmlns:xsi
namespaces.Add(string.Empty, string.Empty);
XmlSerializer serializer = new XmlSerializer(obj.GetType());
//序列化时增加namespaces
serializer.Serialize(sw, obj, namespaces);
sw.Close(); string replaceStr = sw.ToString().Replace(@"<?xml version=""1.0"" encoding=""utf-16""?>", "");
return replaceStr;
}
}
catch (Exception ex)
{
if (isThrowException)
{
throw ex;
}
return string.Empty;
} } #endregion
Xml字符处理
#region Xml字符处理 /// <summary>
/// 特殊符号转换为转义字符
/// </summary>
/// <param name="xmlStr"></param>
/// <returns></returns>
public string XmlSpecialSymbolConvert(string xmlStr)
{
return xmlStr.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("\'", "'").Replace("\"", """);
} #endregion
创建Xml文档
#region 创建Xml文档 /// <summary>
/// 创建Xml文档
/// </summary>
/// <param name="saveFilePath">文件保存位置</param>
public void CreateXmlDocument(string saveFilePath)
{
XmlDocument xmlDoc = new XmlDocument();
//创建类型声明节点
XmlNode node = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "");
xmlDoc.AppendChild(node);
//创建Xml根节点
XmlNode root = xmlDoc.CreateElement("books");
xmlDoc.AppendChild(root); XmlNode root1 = xmlDoc.CreateElement("book");
root.AppendChild(root1); //创建子节点
CreateNode(xmlDoc, root1, "author", "追逐时光者");
CreateNode(xmlDoc, root1, "title", "XML学习教程");
CreateNode(xmlDoc, root1, "publisher", "时光出版社"); //将文件保存到指定位置
xmlDoc.Save(saveFilePath/*"D://xmlSampleCreateFile.xml"*/);
} /// <summary>
/// 创建节点
/// </summary>
/// <param name="xmlDoc">xml文档</param>
/// <param name="parentNode">Xml父节点</param>
/// <param name="name">节点名</param>
/// <param name="value">节点值</param>
///
public void CreateNode(XmlDocument xmlDoc, XmlNode parentNode, string name, string value)
{
//创建对应Xml节点元素
XmlNode node = xmlDoc.CreateNode(XmlNodeType.Element, name, null);
node.InnerText = value;
parentNode.AppendChild(node);
} #endregion
Xml数据读取
#region Xml数据读取 /// <summary>
/// 读取Xml指定节点中的数据
/// </summary>
/// <param name="filePath">Xml文档路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">读取数据的属性名</param>
/// <returns>string</returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlReadNodeAttributeValue(path, "/books/book", "author")
************************************************/
public static string XmlReadNodeAttributeValue(string filePath, string node, string attribute)
{
string value = "";
try
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNode xmlNode = doc.SelectSingleNode(node);
value = (attribute.Equals("") ? xmlNode.InnerText : xmlNode.Attributes[attribute].Value);
}
catch { }
return value;
} /// <summary>
/// 获得xml文件中指定节点的节点数据
/// </summary>
/// <param name="filePath">Xml文档路径</param>
/// <param name="nodeName">节点名</param>
/// <returns></returns>
public static string GetNodeInfoByNodeName(string filePath, string nodeName)
{
string XmlString = string.Empty;
XmlDocument xml = new XmlDocument();
xml.Load(filePath);
XmlElement root = xml.DocumentElement;
XmlNode node = root.SelectSingleNode("//" + nodeName);
if (node != null)
{
XmlString = node.InnerText;
}
return XmlString;
} /// <summary>
/// 获取某一节点的所有孩子节点的值
/// </summary>
/// <param name="node">要查询的节点</param>
/// <param name="filePath">Xml文档路径</param>
public string[] ReadAllChildallValue(string node, string filePath)
{
int i = 0;
string[] str = { };
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNode xn = doc.SelectSingleNode(node);
XmlNodeList nodelist = xn.ChildNodes; //得到该节点的子节点
if (nodelist.Count > 0)
{
str = new string[nodelist.Count];
foreach (XmlElement el in nodelist)//读元素值
{
str[i] = el.Value;
i++;
}
}
return str;
} /// <summary>
/// 获取某一节点的所有孩子节点的值
/// </summary>
/// <param name="node">要查询的节点</param>
/// <param name="filePath">Xml文档路径</param>
public XmlNodeList ReadAllChild(string node, string filePath)
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNode xn = doc.SelectSingleNode(node);
XmlNodeList nodelist = xn.ChildNodes; //得到该节点的子节点
return nodelist;
} #endregion
Xml插入数据
#region Xml插入数据 /// <summary>
/// Xml指定节点元素属性插入数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="element">元素名</param>
/// <param name="attribute">属性名</param>
/// <param name="value">属性数据</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlInsertValue(path, "/books", "book", "author", "Value")
************************************************/
public static void XmlInsertValue(string path, string node, string element, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xmlNode = doc.SelectSingleNode(node);
if (element.Equals(""))
{
if (!attribute.Equals(""))
{
XmlElement xe = (XmlElement)xmlNode;
xe.SetAttribute(attribute, value);
}
}
else
{
XmlElement xe = doc.CreateElement(element);
if (attribute.Equals(""))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
//添加新增的节点
xmlNode.AppendChild(xe);
} //保存Xml文档
doc.Save(path);
}
catch { }
} #endregion
Xml修改数据
#region Xml修改数据 /// <summary>
/// Xml指定节点元素属性修改数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">属性名</param>
/// <param name="value">属性数据</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlUpdateValue(path, "/books", "book","author","Value")
************************************************/
public static void XmlUpdateValue(string path, string node, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xmlNode = doc.SelectSingleNode(node);
XmlElement xmlElement = (XmlElement)xmlNode;
if (attribute.Equals(""))
xmlElement.InnerText = value;
else
xmlElement.SetAttribute(attribute, value); //保存Xml文档
doc.Save(path);
}
catch { }
} #endregion
Xml删除数据
#region Xml删除数据 /// <summary>
/// 删除数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">属性名</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlDelete(path, "/books", "book")
************************************************/
public static void XmlDelete(string path, string node, string attribute)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(""))
xn.ParentNode.RemoveChild(xn);
else
xe.RemoveAttribute(attribute);
doc.Save(path);
}
catch { }
} #endregion
完整的XmlHelper帮助类
注意:有些方法不能保证百分之百没有问题的,假如有问题可以留言给我,我会验证并立即修改。
/// <summary>
/// Xml帮助类
/// </summary>
public class XMLHelper
{
#region Xml反序列化为对象 /// <summary>
/// Xml反序列化为指定模型对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="xmlContent">Xml内容</param>
/// <param name="isThrowException">是否抛出异常</param>
/// <returns></returns>
public static T XmlConvertToModel<T>(string xmlContent, bool isThrowException = false) where T : class
{
StringReader stringReader = null;
try
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
stringReader = new StringReader(xmlContent);
return (T)xmlSerializer.Deserialize(stringReader);
}
catch (Exception ex)
{
if (isThrowException)
{
throw ex;
}
return null;
}
finally
{
stringReader?.Dispose();
}
} /// <summary>
/// 读取Xml文件内容反序列化为指定的对象
/// </summary>
/// <param name="filePath">Xml文件的位置(绝对路径)</param>
/// <returns></returns>
public static T DeserializeFromXml<T>(string filePath)
{
try
{
if (!File.Exists(filePath))
throw new ArgumentNullException(filePath + " not Exists");
using (StreamReader reader = new StreamReader(filePath))
{
XmlSerializer xs = new XmlSerializer(typeof(T));
T ret = (T)xs.Deserialize(reader);
return ret;
}
}
catch (Exception ex)
{
return default(T);
}
} #endregion #region 对象序列化为Xml /// <summary>
/// 对象序列化为Xml
/// </summary>
/// <param name="obj">对象</param>
/// <param name="isThrowException">是否抛出异常</param>
/// <returns></returns>
public static string ObjectSerializerXml<T>(T obj, bool isThrowException = false)
{
if (obj == null)
{
return string.Empty;
} try
{
using (StringWriter sw = new StringWriter())
{
Type t = obj.GetType();
//强制指定命名空间,覆盖默认的命名空间
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
//在Xml序列化时去除默认命名空间xmlns:xsd和xmlns:xsi
namespaces.Add(string.Empty, string.Empty);
XmlSerializer serializer = new XmlSerializer(obj.GetType());
//序列化时增加namespaces
serializer.Serialize(sw, obj, namespaces);
sw.Close(); string replaceStr = sw.ToString().Replace(@"<?xml version=""1.0"" encoding=""utf-16""?>", "");
return replaceStr;
}
}
catch (Exception ex)
{
if (isThrowException)
{
throw ex;
}
return string.Empty;
} } #endregion #region Xml字符处理 /// <summary>
/// 特殊符号转换为转义字符
/// </summary>
/// <param name="xmlStr"></param>
/// <returns></returns>
public string XmlSpecialSymbolConvert(string xmlStr)
{
return xmlStr.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("\'", "'").Replace("\"", """);
} #endregion #region 创建Xml文档 /// <summary>
/// 创建Xml文档
/// </summary>
/// <param name="saveFilePath">文件保存位置</param>
public void CreateXmlDocument(string saveFilePath)
{
XmlDocument xmlDoc = new XmlDocument();
//创建类型声明节点
XmlNode node = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "");
xmlDoc.AppendChild(node);
//创建Xml根节点
XmlNode root = xmlDoc.CreateElement("books");
xmlDoc.AppendChild(root); XmlNode root1 = xmlDoc.CreateElement("book");
root.AppendChild(root1); //创建子节点
CreateNode(xmlDoc, root1, "author", "追逐时光者");
CreateNode(xmlDoc, root1, "title", "XML学习教程");
CreateNode(xmlDoc, root1, "publisher", "时光出版社"); //将文件保存到指定位置
xmlDoc.Save(saveFilePath/*"D://xmlSampleCreateFile.xml"*/);
} /// <summary>
/// 创建节点
/// </summary>
/// <param name="xmlDoc">xml文档</param>
/// <param name="parentNode">Xml父节点</param>
/// <param name="name">节点名</param>
/// <param name="value">节点值</param>
///
public void CreateNode(XmlDocument xmlDoc, XmlNode parentNode, string name, string value)
{
//创建对应Xml节点元素
XmlNode node = xmlDoc.CreateNode(XmlNodeType.Element, name, null);
node.InnerText = value;
parentNode.AppendChild(node);
} #endregion #region Xml数据读取 /// <summary>
/// 读取Xml指定节点中的数据
/// </summary>
/// <param name="filePath">Xml文档路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">读取数据的属性名</param>
/// <returns>string</returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlReadNodeAttributeValue(path, "/books/book", "author")
************************************************/
public static string XmlReadNodeAttributeValue(string filePath, string node, string attribute)
{
string value = "";
try
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNode xmlNode = doc.SelectSingleNode(node);
value = (attribute.Equals("") ? xmlNode.InnerText : xmlNode.Attributes[attribute].Value);
}
catch { }
return value;
} /// <summary>
/// 获得xml文件中指定节点的节点数据
/// </summary>
/// <param name="filePath">Xml文档路径</param>
/// <param name="nodeName">节点名</param>
/// <returns></returns>
public static string GetNodeInfoByNodeName(string filePath, string nodeName)
{
string XmlString = string.Empty;
XmlDocument xml = new XmlDocument();
xml.Load(filePath);
XmlElement root = xml.DocumentElement;
XmlNode node = root.SelectSingleNode("//" + nodeName);
if (node != null)
{
XmlString = node.InnerText;
}
return XmlString;
} /// <summary>
/// 获取某一节点的所有孩子节点的值
/// </summary>
/// <param name="node">要查询的节点</param>
/// <param name="filePath">Xml文档路径</param>
public string[] ReadAllChildallValue(string node, string filePath)
{
int i = 0;
string[] str = { };
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNode xn = doc.SelectSingleNode(node);
XmlNodeList nodelist = xn.ChildNodes; //得到该节点的子节点
if (nodelist.Count > 0)
{
str = new string[nodelist.Count];
foreach (XmlElement el in nodelist)//读元素值
{
str[i] = el.Value;
i++;
}
}
return str;
} /// <summary>
/// 获取某一节点的所有孩子节点的值
/// </summary>
/// <param name="node">要查询的节点</param>
/// <param name="filePath">Xml文档路径</param>
public XmlNodeList ReadAllChild(string node, string filePath)
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNode xn = doc.SelectSingleNode(node);
XmlNodeList nodelist = xn.ChildNodes; //得到该节点的子节点
return nodelist;
} #endregion #region Xml插入数据 /// <summary>
/// Xml指定节点元素属性插入数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="element">元素名</param>
/// <param name="attribute">属性名</param>
/// <param name="value">属性数据</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlInsertValue(path, "/books", "book", "author", "Value")
************************************************/
public static void XmlInsertValue(string path, string node, string element, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xmlNode = doc.SelectSingleNode(node);
if (element.Equals(""))
{
if (!attribute.Equals(""))
{
XmlElement xe = (XmlElement)xmlNode;
xe.SetAttribute(attribute, value);
}
}
else
{
XmlElement xe = doc.CreateElement(element);
if (attribute.Equals(""))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
//添加新增的节点
xmlNode.AppendChild(xe);
} //保存Xml文档
doc.Save(path);
}
catch { }
} #endregion #region Xml修改数据 /// <summary>
/// Xml指定节点元素属性修改数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">属性名</param>
/// <param name="value">属性数据</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlUpdateValue(path, "/books", "book","author","Value")
************************************************/
public static void XmlUpdateValue(string path, string node, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xmlNode = doc.SelectSingleNode(node);
XmlElement xmlElement = (XmlElement)xmlNode;
if (attribute.Equals(""))
xmlElement.InnerText = value;
else
xmlElement.SetAttribute(attribute, value); //保存Xml文档
doc.Save(path);
}
catch { }
} #endregion #region Xml删除数据 /// <summary>
/// 删除数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">属性名</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.XmlDelete(path, "/books", "book")
************************************************/
public static void XmlDelete(string path, string node, string attribute)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(""))
xn.ParentNode.RemoveChild(xn);
else
xe.RemoveAttribute(attribute);
doc.Save(path);
}
catch { }
} #endregion
}
C#XmlHelper帮助类操作Xml文档的通用方法汇总的更多相关文章
- XML DOM (Document Object Model) 定义了访问和操作 XML 文档的标准方法。
XML DOM DOM 把 XML 文档视为一种树结构.通过这个 DOM 树,可以访问所有的元素.可以修改它们的内容(文本以及属性),而且可以创建新的元素.元素,以及它们的文本和属性,均被视为节点. ...
- 使用dom4j类操作xml文档
dom4j操作xml数据 1.Document对象相关 ①读取XML文件,获得document对象. SAXReader reader = new SAXReader(); Document docu ...
- 操作xml文档的常用方式
1.操作XML文档的两种常用方式: 1)使用XmlReader类和XmlWriter类操作 XmlReader是基于数据流的,占用极少的内存,是只读方式的,所以速度极快.只能采用遍历的模式查找数据节点 ...
- 文档对象模型操作xml文档
简介 :文档对象模型(DOM)是一种用于处理xml文档的API函数集. 2.1文档对象模型概述 按照W3C的定义,DOM是“一种允许程序或脚本动态地访问更新文档内容,结构和样式的.独立于平台和语言的规 ...
- XPath操作XML文档
NET框架下的Sytem.Xml.XPath命名空间提供了一系列的类,允许应用XPath数据模式查询和展示XML文档数据. 3.1XPath介绍 主要的目的是在xml1.0和1.1文档节点树种定位节点 ...
- 操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP)
原文:操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP) 不管是用 PHP 还是 C#, 在操作 XML 的时候我们除了一个节点一个节点去取值之外, 还有一个非常方便的表达式, 就是 ...
- JDOM生成XML文档的一般方法
由于DOM提供的生成XML的方法不够直观,而且要用到各种繁琐的注解,鉴于此可借助第三方库-----JDOM生成XML文档.具体操作方式如下: import java.io.FileOutputStre ...
- C#XmlHelper操作Xml文档的帮助类
using System.Xml; using System.Data; namespace DotNet.Utilities { /// <summary> /// Xml的操作公共类 ...
- [XML] C# XmlHelper操作Xml文档的帮助类 (转载)
点击下载 XmlHelper.rar 主要功能如下所示 /// <summary> /// 类说明:XmlHelper /// 编 码 人:苏飞 /// 联系方式:361983679 // ...
随机推荐
- Solution -「POJ 3710」Christmas Game
\(\mathcal{Decription}\) Link. 定义一棵圣诞树: 是仙人掌. 不存在两个同一环上的点,度数均 \(\ge 3\). 给出 \(n\) 棵互不相关的圣诞树,双人 ...
- shell脚本部署zookeeper-3.4.10 [含注释]
文章目录 zk_install.sh conf/config conf/zoo_template.cfg package zk_install.sh #!/bin/bash base_path=$(c ...
- 操作系统实验一:进程管理(含成功运行C语言源代码)
目录 操作系统实验一:进程管理 1.实验目的 2.实验内容 3.实验准备 3.1.1进程的含义 3.1.2进程的状态 3.1.3进程状态之间的转换 3.2 进程控制块PCB 3.2.1进程控制块的作用 ...
- MySQL高级优化
MySQL高级 1.索引是什么? (1)索引是排好序可以快速查找的数据结构 (2)方便快速查找,索引实际上也是一张表所以也是要占内存的 2.索引存在哪里? (1)InnoDB引擎 ①索引是和数据存放在 ...
- react中配置路由
一个路由就是一个通道,页面之间的跳转其实就是路由的切换,所以每个应用的路由配置是必须的,浅谈react中怎么配置路由 首先你要在src文件夹下新建一个router的文件下,在router文件下新建一个 ...
- 攻防世界-Crypto高手进阶区部分Writeup
1.flag_in_your_hand && flag_in_your_hand1 下载,解压后 打开index文件,直接点击get flag错误,输入其他点击也同样 打开js文件,在 ...
- Java8新特性系列-Lambda
转载自:Java8新特性系列-Lambda – 微爱博客 Lambda Expressions in Java 8 Lambda 表达式是 Java 8 最流行的特性.它们将函数式编程概念引入 Jav ...
- MySQL:一些操作
参考:MySQL使用教程 写在开头:语句后都要注意加分号; 1.MySQL服务,在普通的cmd而不是MySQL cmd下进行 --停止MySQL服务 net stop mysql80 --启动MySQ ...
- 对element-ui的table组件的二次封装
首先,使用过element-ui的table组建的同学都知道,每次使用的时候表头字段都要一个一个的去写,写起来很麻烦,既不美观又浪费时间,基于以上原因,对table组件进行二次封装,使我们在使用的时候 ...
- 对于处理datetime数据类型的一些常用方法:
datetime数据类型常用方法: 在项目中从数据库中取出数据后通常需要先绘制图像进行数据的观察,此过程中使用到的方法: 1.时间数据类似于 2022-03-23 14:21:45 可以先转换为dat ...