XmlHelper.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Xml;
  8. namespace MqttMsgServer.Tools
  9. {
  10. public class XmlHelper
  11. {
  12. #region 公共变量
  13. XmlDocument xmldoc;
  14. XmlNode xmlnode;
  15. XmlElement xmlelem;
  16. #endregion
  17. #region 创建Xml文档
  18. /// <summary>
  19. /// 创建一个带有根节点的Xml文件
  20. /// </summary>
  21. /// <paramname="fileName">Xml文件名称</param>
  22. /// <paramname="rootName">根节点名称</param>
  23. /// <paramname="encode">编码方式:gb2312,UTF-8等常见的</param>
  24. /// <paramname="DirPath">保存的目录路径</param>
  25. ///<returns></returns>
  26. public bool CreateXmlDocument(string fileName, string rootName, string encode)
  27. {
  28. try
  29. {
  30. xmldoc = new XmlDocument();
  31. XmlDeclaration xmldecl;
  32. xmldecl = xmldoc.CreateXmlDeclaration("1.0", encode, null);
  33. xmldoc.AppendChild(xmldecl);
  34. xmlelem = xmldoc.CreateElement("", rootName, "");
  35. xmldoc.AppendChild(xmlelem);
  36. xmldoc.Save(fileName);
  37. return true;
  38. }
  39. catch (Exception e)
  40. {
  41. return false;
  42. throw new Exception(e.Message);
  43. }
  44. }
  45. #endregion
  46. #region 常用操作方法(增删改)
  47. /// <summary>
  48. /// 插入一个节点和它的若干子节点
  49. /// </summary>
  50. /// <paramname="XmlFile">Xml文件路径</param>
  51. /// <paramname="NewNodeName">插入的节点名称</param>
  52. /// <paramname="HasAttributes">此节点是否具有属性,True为有,False为无</param>
  53. /// <paramname="fatherNode">此插入节点的父节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
  54. /// <paramname="htAtt">此节点的属性,Key为属性名,Value为属性值</param>
  55. /// <paramname="htSubNode">子节点的属性,Key为Name,Value为InnerText</param>
  56. /// <returns>返回真为更新成功,否则失败</returns>
  57. public bool InsertNode(string XmlFile, string NewNodeName, bool HasAttributes, string fatherNode, Hashtable htAtt, Hashtable htSubNode)
  58. {
  59. try
  60. {
  61. xmldoc = new XmlDocument();
  62. xmldoc.Load(XmlFile);
  63. XmlNode root = xmldoc.SelectSingleNode(fatherNode);
  64. xmlelem = xmldoc.CreateElement(NewNodeName);
  65. if (htAtt != null && HasAttributes)//若此节点有属性,则先添加属性
  66. {
  67. SetAttributes(xmlelem, htAtt);
  68. SetNodes(xmlelem.Name, xmldoc, xmlelem, htSubNode);//添加完此节点属性后,再添加它的子节点和它们的InnerText
  69. }
  70. else
  71. {
  72. SetNodes(xmlelem.Name, xmldoc, xmlelem, htSubNode);//若此节点无属性,那么直接添加它的子节点
  73. }
  74. root?.AppendChild(xmlelem);
  75. xmldoc.Save(XmlFile);
  76. return true;
  77. }
  78. catch (Exception e)
  79. {
  80. throw new Exception(e.Message);
  81. }
  82. }
  83. /// <summary>
  84. /// 更新节点
  85. /// </summary>
  86. /// <paramname="XmlFile">Xml文件路径</param>
  87. /// <paramname="fatherNode">需要更新节点的上级节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
  88. /// <paramname="htAtt">需要更新的属性表,Key代表需要更新的属性,Value代表更新后的值</param>
  89. /// <param name="htSubNode">需要更新的子节点的属性表,Key代表需要更新的子节点名字Name,Value代表更新后的值InnerText</param>
  90. /// <returns>返回真为更新成功,否则失败</returns>
  91. public bool UpdateNode(string XmlFile, string fatherNode, Hashtable htAtt, Hashtable htSubNode)
  92. {
  93. try
  94. {
  95. xmldoc = new XmlDocument();
  96. xmldoc.Load(XmlFile);
  97. XmlNodeList root = xmldoc.SelectSingleNode(fatherNode).ChildNodes;
  98. UpdateNodes(root, htAtt, htSubNode);
  99. xmldoc.Save(XmlFile);
  100. return true;
  101. }
  102. catch (Exception e)
  103. {
  104. throw new Exception(e.Message);
  105. }
  106. }
  107. /// <summary>
  108. /// 删除指定节点下的子节点
  109. /// </summary>
  110. /// <paramname="XmlFile">Xml文件路径</param>
  111. /// <paramname="fatherNode">制定节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
  112. /// <returns>返回真为更新成功,否则失败</returns>
  113. public bool DeleteNodes(string XmlFile, string fatherNode)
  114. {
  115. try
  116. {
  117. xmldoc = new XmlDocument();
  118. xmldoc.Load(XmlFile);
  119. xmlnode = xmldoc.SelectSingleNode(fatherNode);
  120. xmlnode.RemoveAll();
  121. xmldoc.Save(XmlFile);
  122. return true;
  123. }
  124. catch (XmlException xe)
  125. {
  126. throw new XmlException(xe.Message);
  127. }
  128. }
  129. /// <summary>
  130. /// 删除匹配XPath表达式的第一个节点(节点中的子元素同时会被删除)
  131. /// </summary>
  132. /// <paramname="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  133. /// <paramname="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  134. /// <returns>成功返回true,失败返回false</returns>
  135. public bool DeleteXmlNodeByXPath(string xmlFileName, string xpath)
  136. {
  137. xmldoc = new XmlDocument();
  138. xmldoc.Load(xmlFileName); //加载XML文档
  139. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  140. if (xmlNode != null)
  141. {
  142. //删除节点
  143. xmldoc?.ParentNode?.RemoveChild(xmlNode);
  144. }
  145. xmldoc.Save(xmlFileName); //保存到XML文档
  146. return true;
  147. }
  148. /// <summary>
  149. /// 删除匹配XPath表达式的第一个节点中的匹配参数xmlAttributeName的属性
  150. /// </summary>
  151. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  152. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  153. /// <param name="xmlAttributeName">要删除的xmlAttributeName的属性名称</param>
  154. /// <returns>成功返回true,失败返回false</returns>
  155. public bool DeleteXmlAttributeByXPath(string xmlFileName, string xpath, string xmlAttributeName)
  156. {
  157. bool isSuccess = false;
  158. bool isExistsAttribute = false;
  159. xmldoc = new XmlDocument();
  160. try
  161. {
  162. xmldoc.Load(xmlFileName); //加载XML文档
  163. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  164. XmlAttribute xmlAttribute = null;
  165. if (xmlNode != null)
  166. {
  167. //遍历xpath节点中的所有属性
  168. if (xmlNode?.Attributes != null)
  169. {
  170. foreach (XmlAttribute attribute in xmlNode.Attributes)
  171. {
  172. if (attribute.Name.ToLower() == xmlAttributeName.ToLower())
  173. {
  174. //节点中存在此属性
  175. xmlAttribute = attribute;
  176. isExistsAttribute = true;
  177. break;
  178. }
  179. }
  180. if (isExistsAttribute)
  181. {
  182. //删除节点中的属性
  183. xmlNode.Attributes.Remove(xmlAttribute);
  184. }
  185. }
  186. }
  187. xmldoc.Save(xmlFileName); //保存到XML文档
  188. isSuccess = true;
  189. }
  190. catch (Exception ex)
  191. {
  192. throw ex; //这里可以定义你自己的异常处理
  193. }
  194. return isSuccess;
  195. }
  196. /// <summary>
  197. /// 删除匹配XPath表达式的第一个节点中的所有属性
  198. /// </summary>
  199. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  200. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  201. /// <returns>成功返回true,失败返回false</returns>
  202. public bool DeleteAllXmlAttributeByXPath(string xmlFileName, string xpath)
  203. {
  204. bool isSuccess = false;
  205. xmldoc = new XmlDocument();
  206. try
  207. {
  208. xmldoc.Load(xmlFileName); //加载XML文档
  209. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  210. if (xmlNode != null)
  211. {
  212. //遍历xpath节点中的所有属性
  213. xmlNode.Attributes?.RemoveAll();
  214. }
  215. xmldoc.Save(xmlFileName); //保存到XML文档
  216. isSuccess = true;
  217. }
  218. catch (Exception ex)
  219. {
  220. throw ex; //这里可以定义你自己的异常处理
  221. }
  222. return isSuccess;
  223. }
  224. #endregion
  225. #region 私有方法
  226. /// <summary>
  227. /// 设置节点属性
  228. /// </summary>
  229. /// <paramname="xe">节点所处的Element</param>
  230. /// <paramname="htAttribute">节点属性,Key代表属性名称,Value代表属性值</param>
  231. private void SetAttributes(XmlElement xe, Hashtable htAttribute)
  232. {
  233. foreach (DictionaryEntry de in htAttribute)
  234. {
  235. xe.SetAttribute(de.Key.ToString(), de.Value.ToString());
  236. }
  237. }
  238. /// <summary>
  239. /// 增加子节点到根节点下
  240. /// </summary>
  241. /// <paramname="rootNode">上级节点名称</param>
  242. /// <paramname="XmlDoc">Xml文档</param>
  243. /// <paramname="rootXe">父根节点所属的Element</param>
  244. /// <paramname="SubNodes">子节点属性,Key为Name值,Value为InnerText值</param>
  245. private void SetNodes(string rootNode, XmlDocument XmlDoc, XmlElement rootXe, Hashtable SubNodes)
  246. {
  247. if (SubNodes == null)
  248. return;
  249. foreach (DictionaryEntry de in SubNodes)
  250. {
  251. xmlnode = XmlDoc.SelectSingleNode(rootNode);
  252. XmlElement subNode = XmlDoc.CreateElement(de.Key.ToString());
  253. subNode.InnerText = de.Value.ToString();
  254. rootXe.AppendChild(subNode);
  255. }
  256. }
  257. /// <summary>
  258. /// 更新节点属性和子节点InnerText值。
  259. /// </summary>
  260. /// <paramname="root">根节点名字</param>
  261. /// <paramname="htAtt">需要更改的属性名称和值</param>
  262. /// <paramname="htSubNode">需要更改InnerText的子节点名字和值</param>
  263. private void UpdateNodes(XmlNodeList root, Hashtable htAtt, Hashtable htSubNode)
  264. {
  265. foreach (XmlNode xn in root)
  266. {
  267. xmlelem = (XmlElement)xn;
  268. if (xmlelem.HasAttributes)//如果节点如属性,则先更改它的属性
  269. {
  270. foreach (DictionaryEntry de in htAtt)//遍历属性哈希表
  271. {
  272. if (xmlelem.HasAttribute(de.Key.ToString()))//如果节点有需要更改的属性
  273. {
  274. xmlelem.SetAttribute(de.Key.ToString(), de.Value.ToString());//则把哈希表中相应的值Value赋给此属性Key
  275. }
  276. }
  277. }
  278. if (xmlelem.HasChildNodes)//如果有子节点,则修改其子节点的InnerText
  279. {
  280. XmlNodeList xnl = xmlelem.ChildNodes;
  281. foreach (XmlNode xn1 in xnl)
  282. {
  283. XmlElement xe = (XmlElement)xn1;
  284. foreach (DictionaryEntry de in htSubNode)
  285. {
  286. if (xe.Name == de.Key.ToString())//htSubNode中的key存储了需要更改的节点名称,
  287. {
  288. xe.InnerText = de.Value.ToString();//htSubNode中的Value存储了Key节点更新后的数据
  289. }
  290. }
  291. }
  292. }
  293. }
  294. }
  295. #endregion
  296. #region XML文档节点查询和读取
  297. /// <summary>
  298. /// 选择匹配XPath表达式的第一个节点XmlNode.
  299. /// </summary>
  300. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  301. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
  302. /// <returns>返回XmlNode</returns>
  303. public XmlNode GetXmlNodeByXpath(string xmlFileName, string xpath)
  304. {
  305. xmldoc = new XmlDocument();
  306. try
  307. {
  308. xmldoc.Load(xmlFileName); //加载XML文档
  309. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  310. return xmlNode;
  311. }
  312. catch (Exception ex)
  313. {
  314. return null;
  315. //throw ex; //这里可以定义你自己的异常处理
  316. }
  317. }
  318. /**/
  319. /// <summary>
  320. /// 选择匹配XPath表达式的节点列表XmlNodeList.
  321. /// </summary>
  322. /// <paramname="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  323. /// <paramname="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
  324. /// <returns>返回XmlNodeList</returns>
  325. public XmlNodeList GetXmlNodeListByXpath(string xmlFileName, string xpath)
  326. {
  327. xmldoc = new XmlDocument();
  328. try
  329. {
  330. xmldoc.Load(xmlFileName); //加载XML文档
  331. XmlNodeList xmlNodeList = xmldoc.SelectNodes(xpath);
  332. return xmlNodeList;
  333. }
  334. catch (Exception ex)
  335. {
  336. return null;
  337. //throw ex; //这里可以定义你自己的异常处理
  338. }
  339. }
  340. /**/
  341. /// <summary>
  342. /// 选择匹配XPath表达式的第一个节点的匹配xmlAttributeName的属性XmlAttribute. /// </summary>
  343. /// <paramname="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  344. /// <paramname="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  345. /// <paramname="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
  346. /// <returns>返回xmlAttributeName</returns>
  347. public XmlAttribute GetXmlAttribute(string xmlFileName, string xpath, string xmlAttributeName)
  348. {
  349. string content = string.Empty;
  350. xmldoc = new XmlDocument();
  351. XmlAttribute xmlAttribute = null;
  352. try
  353. {
  354. xmldoc.Load(xmlFileName); //加载XML文档
  355. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  356. if (xmlNode != null)
  357. {
  358. if (xmlNode.Attributes.Count > 0)
  359. {
  360. xmlAttribute = xmlNode.Attributes[xmlAttributeName];
  361. }
  362. }
  363. }
  364. catch (Exception ex)
  365. {
  366. throw ex; //这里可以定义你自己的异常处理
  367. }
  368. return xmlAttribute;
  369. }
  370. #endregion
  371. }
  372. }