XmlHelper.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. using System;
  2. using System.Collections;
  3. using System.Data;
  4. using System.IO;
  5. using System.Text;
  6. using System.Xml;
  7. using System.Xml.Serialization;
  8. namespace WWPipeLine.Commons
  9. {
  10. /// <summary>
  11. /// Xml 序列化和反序列化类
  12. /// </summary>
  13. public class XmlHelper
  14. {
  15. #region 公共变量
  16. XmlDocument xmldoc;
  17. XmlNode xmlnode;
  18. XmlElement xmlelem;
  19. #endregion
  20. #region 创建Xml文档
  21. /// <summary>
  22. /// 创建一个带有根节点的Xml文件
  23. /// </summary>
  24. /// <param name="FileName">Xml文件名称</param>
  25. /// <param name="rootName">根节点名称</param>
  26. /// <param name="Encode">编码方式:gb2312,UTF-8等常见的</param>
  27. /// <param name="DirPath">保存的目录路径</param>
  28. /// <returns></returns>
  29. public bool CreateXmlDocument(string FileName, string RootName, string Encode)
  30. {
  31. try
  32. {
  33. xmldoc = new XmlDocument();
  34. XmlDeclaration xmldecl;
  35. xmldecl = xmldoc.CreateXmlDeclaration("1.0", Encode, null);
  36. xmldoc.AppendChild(xmldecl);
  37. xmlelem = xmldoc.CreateElement("", RootName, "");
  38. xmldoc.AppendChild(xmlelem);
  39. xmldoc.Save(FileName);
  40. return true;
  41. }
  42. catch (Exception e)
  43. {
  44. throw new Exception(e.Message);
  45. }
  46. }
  47. #endregion
  48. #region 常用操作方法(增删改)
  49. /// <summary>
  50. /// 插入一个节点和它的若干子节点
  51. /// </summary>
  52. /// <param name="XmlFile">Xml文件路径</param>
  53. /// <param name="NewNodeName">插入的节点名称</param>
  54. /// <param name="HasAttributes">此节点是否具有属性,True为有,False为无</param>
  55. /// <param name="fatherNode">此插入节点的父节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
  56. /// <param name="htAtt">此节点的属性,Key为属性名,Value为属性值</param>
  57. /// <param name="htSubNode">子节点的属性,Key为Name,Value为InnerText</param>
  58. /// <returns>返回真为更新成功,否则失败</returns>
  59. public bool InsertNode(string XmlFile, string NewNodeName, bool HasAttributes, string fatherNode, Hashtable htAtt, Hashtable htSubNode)
  60. {
  61. try
  62. {
  63. xmldoc = new XmlDocument();
  64. xmldoc.Load(XmlFile);
  65. XmlNode root = xmldoc.SelectSingleNode(fatherNode);
  66. xmlelem = xmldoc.CreateElement(NewNodeName);
  67. if (htAtt != null && HasAttributes)//若此节点有属性,则先添加属性
  68. {
  69. SetAttributes(xmlelem, htAtt);
  70. SetNodes(xmlelem.Name, xmldoc, xmlelem, htSubNode);//添加完此节点属性后,再添加它的子节点和它们的InnerText
  71. }
  72. else
  73. {
  74. SetNodes(xmlelem.Name, xmldoc, xmlelem, htSubNode);//若此节点无属性,那么直接添加它的子节点
  75. }
  76. root.AppendChild(xmlelem);
  77. xmldoc.Save(XmlFile);
  78. return true;
  79. }
  80. catch (Exception e)
  81. {
  82. throw new Exception(e.Message);
  83. }
  84. }
  85. /// <summary>
  86. /// 更新节点
  87. /// </summary>
  88. /// <param name="XmlFile">Xml文件路径</param>
  89. /// <param name="fatherNode">需要更新节点的上级节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
  90. /// <param name="htAtt">需要更新的属性表,Key代表需要更新的属性,Value代表更新后的值</param>
  91. /// <param name="htSubNode">需要更新的子节点的属性表,Key代表需要更新的子节点名字Name,Value代表更新后的值InnerText</param>
  92. /// <returns>返回真为更新成功,否则失败</returns>
  93. public bool UpdateNode(string XmlFile, string fatherNode, Hashtable htAtt, Hashtable htSubNode)
  94. {
  95. try
  96. {
  97. xmldoc = new XmlDocument();
  98. xmldoc.Load(XmlFile);
  99. XmlNodeList root = xmldoc.SelectSingleNode(fatherNode).ChildNodes;
  100. UpdateNodes(root, htAtt, htSubNode);
  101. xmldoc.Save(XmlFile);
  102. return true;
  103. }
  104. catch (Exception e)
  105. {
  106. throw new Exception(e.Message);
  107. }
  108. }
  109. /// <summary>
  110. /// 删除指定节点下的子节点
  111. /// </summary>
  112. /// <param name="XmlFile">Xml文件路径</param>
  113. /// <param name="fatherNode">制定节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
  114. /// <returns>返回真为更新成功,否则失败</returns>
  115. public bool DeleteNodes(string XmlFile, string fatherNode)
  116. {
  117. try
  118. {
  119. xmldoc = new XmlDocument();
  120. xmldoc.Load(XmlFile);
  121. xmlnode = xmldoc.SelectSingleNode(fatherNode);
  122. xmlnode.RemoveAll();
  123. xmldoc.Save(XmlFile);
  124. return true;
  125. }
  126. catch (XmlException xe)
  127. {
  128. throw new XmlException(xe.Message);
  129. }
  130. }
  131. /// <summary>
  132. /// 删除匹配XPath表达式的第一个节点(节点中的子元素同时会被删除)
  133. /// </summary>
  134. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  135. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  136. /// <returns>成功返回true,失败返回false</returns>
  137. public bool DeleteXmlNodeByXPath(string xmlFileName, string xpath)
  138. {
  139. bool isSuccess = false;
  140. xmldoc = new XmlDocument();
  141. try
  142. {
  143. xmldoc.Load(xmlFileName); //加载XML文档
  144. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  145. if (xmlNode != null)
  146. {
  147. //删除节点
  148. xmldoc.ParentNode.RemoveChild(xmlNode);
  149. }
  150. xmldoc.Save(xmlFileName); //保存到XML文档
  151. isSuccess = true;
  152. }
  153. catch (Exception ex)
  154. {
  155. throw ex; //这里可以定义你自己的异常处理
  156. }
  157. return isSuccess;
  158. }
  159. /// <summary>
  160. /// 删除匹配XPath表达式的第一个节点中的匹配参数xmlAttributeName的属性
  161. /// </summary>
  162. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  163. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  164. /// <param name="xmlAttributeName">要删除的xmlAttributeName的属性名称</param>
  165. /// <returns>成功返回true,失败返回false</returns>
  166. public bool DeleteXmlAttributeByXPath(string xmlFileName, string xpath, string xmlAttributeName)
  167. {
  168. bool isSuccess = false;
  169. bool isExistsAttribute = false;
  170. xmldoc = new XmlDocument();
  171. try
  172. {
  173. xmldoc.Load(xmlFileName); //加载XML文档
  174. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  175. XmlAttribute xmlAttribute = null;
  176. if (xmlNode != null)
  177. {
  178. //遍历xpath节点中的所有属性
  179. foreach (XmlAttribute attribute in xmlNode.Attributes)
  180. {
  181. if (attribute.Name.ToLower() == xmlAttributeName.ToLower())
  182. {
  183. //节点中存在此属性
  184. xmlAttribute = attribute;
  185. isExistsAttribute = true;
  186. break;
  187. }
  188. }
  189. if (isExistsAttribute)
  190. {
  191. //删除节点中的属性
  192. xmlNode.Attributes.Remove(xmlAttribute);
  193. }
  194. }
  195. xmldoc.Save(xmlFileName); //保存到XML文档
  196. isSuccess = true;
  197. }
  198. catch (Exception ex)
  199. {
  200. throw ex; //这里可以定义你自己的异常处理
  201. }
  202. return isSuccess;
  203. }
  204. /// <summary>
  205. /// 删除匹配XPath表达式的第一个节点中的所有属性
  206. /// </summary>
  207. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  208. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  209. /// <returns>成功返回true,失败返回false</returns>
  210. public bool DeleteAllXmlAttributeByXPath(string xmlFileName, string xpath)
  211. {
  212. bool isSuccess = false;
  213. xmldoc = new XmlDocument();
  214. try
  215. {
  216. xmldoc.Load(xmlFileName); //加载XML文档
  217. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  218. if (xmlNode != null)
  219. {
  220. //遍历xpath节点中的所有属性
  221. xmlNode.Attributes.RemoveAll();
  222. }
  223. xmldoc.Save(xmlFileName); //保存到XML文档
  224. isSuccess = true;
  225. }
  226. catch (Exception ex)
  227. {
  228. throw ex; //这里可以定义你自己的异常处理
  229. }
  230. return isSuccess;
  231. }
  232. #endregion
  233. #region 私有方法
  234. /// <summary>
  235. /// 设置节点属性
  236. /// </summary>
  237. /// <param name="xe">节点所处的Element</param>
  238. /// <param name="htAttribute">节点属性,Key代表属性名称,Value代表属性值</param>
  239. private void SetAttributes(XmlElement xe, Hashtable htAttribute)
  240. {
  241. foreach (DictionaryEntry de in htAttribute)
  242. {
  243. xe.SetAttribute(de.Key.ToString(), de.Value.ToString());
  244. }
  245. }
  246. /// <summary>
  247. /// 增加子节点到根节点下
  248. /// </summary>
  249. /// <param name="rootNode">上级节点名称</param>
  250. /// <param name="XmlDoc">Xml文档</param>
  251. /// <param name="rootXe">父根节点所属的Element</param>
  252. /// <param name="SubNodes">子节点属性,Key为Name值,Value为InnerText值</param>
  253. private void SetNodes(string rootNode, XmlDocument XmlDoc, XmlElement rootXe, Hashtable SubNodes)
  254. {
  255. if (SubNodes == null)
  256. return;
  257. foreach (DictionaryEntry de in SubNodes)
  258. {
  259. xmlnode = XmlDoc.SelectSingleNode(rootNode);
  260. XmlElement subNode = XmlDoc.CreateElement(de.Key.ToString());
  261. subNode.InnerText = de.Value.ToString();
  262. rootXe.AppendChild(subNode);
  263. }
  264. }
  265. /// <summary>
  266. /// 更新节点属性和子节点InnerText值。柯 乐 义
  267. /// </summary>
  268. /// <param name="root">根节点名字</param>
  269. /// <param name="htAtt">需要更改的属性名称和值</param>
  270. /// <param name="htSubNode">需要更改InnerText的子节点名字和值</param>
  271. private void UpdateNodes(XmlNodeList root, Hashtable htAtt, Hashtable htSubNode)
  272. {
  273. foreach (XmlNode xn in root)
  274. {
  275. xmlelem = (XmlElement)xn;
  276. if (xmlelem.HasAttributes)//如果节点如属性,则先更改它的属性
  277. {
  278. foreach (DictionaryEntry de in htAtt)//遍历属性哈希表
  279. {
  280. if (xmlelem.HasAttribute(de.Key.ToString()))//如果节点有需要更改的属性
  281. {
  282. xmlelem.SetAttribute(de.Key.ToString(), de.Value.ToString());//则把哈希表中相应的值Value赋给此属性Key
  283. }
  284. }
  285. }
  286. if (xmlelem.HasChildNodes)//如果有子节点,则修改其子节点的InnerText
  287. {
  288. XmlNodeList xnl = xmlelem.ChildNodes;
  289. foreach (XmlNode xn1 in xnl)
  290. {
  291. XmlElement xe = (XmlElement)xn1;
  292. foreach (DictionaryEntry de in htSubNode)
  293. {
  294. if (xe.Name == de.Key.ToString())//htSubNode中的key存储了需要更改的节点名称,
  295. {
  296. xe.InnerText = de.Value.ToString();//htSubNode中的Value存储了Key节点更新后的数据
  297. }
  298. }
  299. }
  300. }
  301. }
  302. }
  303. #endregion
  304. #region XML文档节点查询和读取
  305. /// <summary>
  306. /// 选择匹配XPath表达式的第一个节点XmlNode.
  307. /// </summary>
  308. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  309. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
  310. /// <returns>返回XmlNode</returns>
  311. public XmlNode GetXmlNodeByXpath(string xmlFileName, string xpath)
  312. {
  313. xmldoc = new XmlDocument();
  314. try
  315. {
  316. xmldoc.Load(xmlFileName); //加载XML文档
  317. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  318. return xmlNode;
  319. }
  320. catch (Exception ex)
  321. {
  322. throw ex; //这里可以定义你自己的异常处理
  323. }
  324. }
  325. /// <summary>
  326. /// 选择匹配XPath表达式的节点列表XmlNodeList.
  327. /// </summary>
  328. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  329. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
  330. /// <returns>返回XmlNodeList</returns>
  331. public XmlNodeList GetXmlNodeListByXpath(string xmlFileName, string xpath)
  332. {
  333. xmldoc = new XmlDocument();
  334. try
  335. {
  336. xmldoc.Load(xmlFileName); //加载XML文档
  337. XmlNodeList xmlNodeList = xmldoc.SelectNodes(xpath);
  338. return xmlNodeList;
  339. }
  340. catch (Exception ex)
  341. {
  342. throw ex; //这里可以定义你自己的异常处理
  343. }
  344. }
  345. /// <summary>
  346. /// 选择匹配XPath表达式的第一个节点的匹配xmlAttributeName的属性XmlAttribute
  347. /// </summary>
  348. /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
  349. /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
  350. /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
  351. /// <returns>返回xmlAttributeName</returns>
  352. public XmlAttribute GetXmlAttribute(string xmlFileName, string xpath, string xmlAttributeName)
  353. {
  354. string content = string.Empty;
  355. xmldoc = new XmlDocument();
  356. XmlAttribute xmlAttribute = null;
  357. try
  358. {
  359. xmldoc.Load(xmlFileName); //加载XML文档
  360. XmlNode xmlNode = xmldoc.SelectSingleNode(xpath);
  361. if (xmlNode != null)
  362. {
  363. if (xmlNode.Attributes.Count > 0)
  364. {
  365. xmlAttribute = xmlNode.Attributes[xmlAttributeName];
  366. }
  367. }
  368. }
  369. catch (Exception ex)
  370. {
  371. throw ex; //这里可以定义你自己的异常处理
  372. }
  373. return xmlAttribute;
  374. }
  375. #endregion
  376. /// <summary>
  377. /// 序列化对象为XML文件
  378. /// </summary>
  379. /// <typeparam name="T">序列化对象</typeparam>
  380. /// <param name="fileName">序列化文件路径</param>
  381. /// <param name="t">序列化对象</param>
  382. /// <returns></returns>
  383. public static bool SerializedToXml<T>(string fileName, T t)
  384. {
  385. try
  386. {
  387. Type paramType = t.GetType();
  388. XmlSerializer xmls = new XmlSerializer(paramType);
  389. using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
  390. {
  391. xmls.Serialize(fs, t);
  392. }
  393. return true;
  394. }
  395. catch (Exception ex)
  396. {
  397. System.Diagnostics.Debug.WriteLine("Serialize xml Error:" + ex.ToString());
  398. return false;
  399. }
  400. }
  401. /// <summary>
  402. /// 反序列化对象
  403. /// </summary>
  404. /// <typeparam name="T">反序列化的对象</typeparam>
  405. /// <param name="fileName">反序列化文件的路径</param>
  406. /// <param name="t">反序列化出来的路径</param>
  407. /// <returns></returns>
  408. public static bool DeSerializedFromXml<T>(string fileName, ref T t)
  409. {
  410. try
  411. {
  412. Type paramType = t.GetType();
  413. XmlSerializer xmls = new XmlSerializer(paramType);
  414. using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
  415. {
  416. t = (T)xmls.Deserialize(fs);
  417. }
  418. return true;
  419. }
  420. catch (Exception ex)
  421. {
  422. System.Diagnostics.Debug.WriteLine("DeSerialize xml Error:" + ex.ToString());
  423. return false;
  424. }
  425. }
  426. /// <summary>
  427. /// 将xml对象内容字符串转换为DataSet
  428. /// </summary>
  429. /// <param name="xmlData"></param>
  430. /// <returns></returns>
  431. public static DataSet ConvertXMLToDataSet(string xmlData)
  432. {
  433. XmlTextReader reader = null;
  434. try
  435. {
  436. DataSet xmlDS = new DataSet();
  437. StringReader stream = new StringReader(xmlData);
  438. reader = new XmlTextReader(stream);
  439. xmlDS.ReadXml(reader);
  440. return xmlDS;
  441. }
  442. catch (System.Exception ex)
  443. {
  444. throw ex;
  445. }
  446. finally
  447. {
  448. if (reader != null) reader.Close();
  449. }
  450. }
  451. /// <summary>
  452. /// 将xml文件转换为DataSet
  453. /// </summary>
  454. /// <param name="xmlFile"></param>
  455. /// <returns></returns>
  456. public static DataSet ConvertXMLFileToDataSet(string xmlFile)
  457. {
  458. XmlTextReader reader = null;
  459. try
  460. {
  461. XmlDocument xmld = new XmlDocument();
  462. xmld.Load(xmlFile);
  463. DataSet xmlDS = new DataSet();
  464. StringReader stream = new StringReader(xmld.InnerXml);
  465. reader = new XmlTextReader(stream);
  466. xmlDS.ReadXml(reader);
  467. return xmlDS;
  468. }
  469. catch (System.Exception ex)
  470. {
  471. throw ex;
  472. }
  473. finally
  474. {
  475. if (reader != null) reader.Close();
  476. }
  477. }
  478. /// <summary>
  479. /// 将DataSet转换为xml对象字符串
  480. /// </summary>
  481. /// <param name="xmlDS"></param>
  482. /// <returns></returns>
  483. public static string ConvertDataSetToXML(DataSet xmlDS)
  484. {
  485. XmlTextWriter writer = null;
  486. try
  487. {
  488. MemoryStream stream = new MemoryStream();
  489. writer = new XmlTextWriter(stream, Encoding.Unicode);
  490. xmlDS.WriteXml(writer);
  491. int count = (int)stream.Length;
  492. byte[] arr = new byte[count];
  493. stream.Seek(0, SeekOrigin.Begin);
  494. stream.Read(arr, 0, count);
  495. UnicodeEncoding utf = new UnicodeEncoding();
  496. return utf.GetString(arr).Trim();
  497. }
  498. catch (System.Exception ex)
  499. {
  500. throw ex;
  501. }
  502. finally
  503. {
  504. if (writer != null) writer.Close();
  505. }
  506. }
  507. /// <summary>
  508. /// 将DataSet转换为xml文件
  509. /// </summary>
  510. /// <param name="xmlDS"></param>
  511. /// <param name="xmlFile"></param>
  512. public static void ConvertDataSetToXMLFile(DataSet xmlDS, string xmlFile)
  513. {
  514. XmlTextWriter writer = null;
  515. try
  516. {
  517. MemoryStream stream = new MemoryStream();
  518. writer = new XmlTextWriter(stream, Encoding.Unicode);
  519. xmlDS.WriteXml(writer);
  520. int count = (int)stream.Length;
  521. byte[] arr = new byte[count];
  522. stream.Seek(0, SeekOrigin.Begin);
  523. stream.Read(arr, 0, count);
  524. UnicodeEncoding utf = new UnicodeEncoding();
  525. StreamWriter sw = new StreamWriter(xmlFile);
  526. sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
  527. sw.WriteLine(utf.GetString(arr).Trim());
  528. sw.Close();
  529. }
  530. catch (System.Exception ex)
  531. {
  532. throw ex;
  533. }
  534. finally
  535. {
  536. if (writer != null) writer.Close();
  537. }
  538. }
  539. }
  540. }