XMLDataEditor.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using System.Xml;
  6. using XRTool.Util;
  7. /// <summary>
  8. /// 一个xml编辑器
  9. /// </summary>
  10. namespace PublicTools.XMLDataBase
  11. {
  12. /// <summary>
  13. /// 针对某个xml文件进行编辑的类
  14. /// </summary>
  15. public class XMLDataEditor : TableInterface
  16. {
  17. private XmlDocument xmlDoc; //可操作的xml文档
  18. private XmlNode xmlRootNode; //根节点
  19. /// <summary>
  20. /// 文件的绝对路径
  21. /// </summary>
  22. private string filePath;
  23. /// <summary>
  24. /// 表格的名称
  25. /// </summary>
  26. private string tableName;
  27. /// <summary>
  28. /// 根节点的名称
  29. /// </summary>
  30. /// <summary>
  31. /// 以绝对路径创建一个对象
  32. /// </summary>
  33. /// <param name="filePath"></param>
  34. public XMLDataEditor(string filePath)
  35. {
  36. this.filePath = filePath;
  37. }
  38. public XMLDataEditor()
  39. {
  40. }
  41. public bool Open()
  42. {
  43. return Open(filePath);
  44. }
  45. /// <summary>
  46. /// 打开xml表格
  47. /// </summary>
  48. /// <param name="path"></param>
  49. /// <returns></returns>
  50. public bool Open(string path)
  51. {
  52. if (xmlDoc != null && !string.IsNullOrEmpty(this.filePath))
  53. {
  54. return true;
  55. }
  56. ///开启之前先关闭
  57. //Close();
  58. if (File.Exists(path))
  59. {
  60. xmlDoc = new XmlDocument();
  61. tableName = Path.GetFileNameWithoutExtension(path);
  62. try
  63. {
  64. xmlDoc.Load(path);
  65. xmlRootNode = xmlDoc.SelectSingleNode(tableName);
  66. return xmlRootNode != null;
  67. }
  68. catch (Exception ex)
  69. {
  70. UnityLog.LogError(path + ex.ToString());
  71. }
  72. }
  73. return false;
  74. }
  75. public void Close()
  76. {
  77. if (xmlDoc != null && !string.IsNullOrEmpty(filePath))
  78. {
  79. try
  80. {
  81. xmlDoc.Save(filePath);
  82. xmlDoc = null;
  83. //filePath = null;
  84. }
  85. catch (Exception ex)
  86. {
  87. UnityLog.LogError(filePath + "\n" + ex.ToString());
  88. }
  89. }
  90. }
  91. public bool InsertData<T>(T data, string priKey)
  92. {
  93. Dictionary<string, string> field = ClazzFactory.ClazzAnalyze(data);
  94. if (field != null && field.Count > 0)
  95. {
  96. XmlNode table = xmlRootNode;
  97. if (string.IsNullOrEmpty(priKey))
  98. {
  99. foreach (var item in field)
  100. {
  101. priKey = item.Value;
  102. break;
  103. }
  104. }
  105. return InsertData<T>(data, table, field, priKey);
  106. }
  107. return false;
  108. }
  109. /// <summary>
  110. /// 插入数据
  111. /// </summary>
  112. /// <typeparam name="T"></typeparam>
  113. /// <param name="table"></param>
  114. /// <param name="field"></param>
  115. private bool InsertData<T>(T data, XmlNode table, Dictionary<string, string> field, string priKey)
  116. {
  117. try
  118. {
  119. if (table.SelectSingleNode(priKey) != null)
  120. {
  121. return UpdateData<T>(data, table, field, priKey);
  122. }
  123. ///添加一条数据
  124. ///按照key值添加一个节点元素
  125. XmlElement element = xmlDoc.CreateElement(priKey);
  126. ///循环遍历变量集合,将类的数据集合起来添加
  127. foreach (var item in field)
  128. {
  129. XmlAttribute xa = xmlDoc.CreateAttribute(item.Key);
  130. xa.Value = item.Value;
  131. element.Attributes.Append(xa);
  132. }
  133. table.AppendChild(element);
  134. return true;
  135. }
  136. catch (Exception ex)
  137. {
  138. UnityLog.LogError(data + " " + priKey + ex.ToString());
  139. Close();
  140. }
  141. return false;
  142. }
  143. public bool InsertData<T>(T data)
  144. {
  145. return InsertData<T>(data, null);
  146. }
  147. /// <summary>
  148. /// 尝试获取xml的一个表,如果此xml没有此表,则创建一个
  149. /// </summary>
  150. /// <param name="tableName"></param>
  151. /// <returns></returns>
  152. public XmlNode TryGetTable(string tableName)
  153. {
  154. XmlNode node = xmlRootNode.SelectSingleNode(tableName);
  155. if (node != null)
  156. {
  157. return node;
  158. }
  159. return CreateTable(tableName);
  160. }
  161. /// <summary>
  162. /// 创建一个子节点
  163. /// </summary>
  164. /// <param name="tableName"></param>
  165. public XmlNode CreateTable(string tableName)
  166. {
  167. XmlNode table = xmlDoc.CreateElement(tableName);
  168. xmlRootNode.AppendChild(table);
  169. Save();
  170. return table;
  171. }
  172. /// <summary>
  173. ///
  174. /// </summary>
  175. /// <typeparam name="T"></typeparam>
  176. /// <param name="priKey"></param>
  177. /// <returns></returns>
  178. public T FindData<T>(string priKey)
  179. {
  180. T t = default(T);
  181. XmlNode table = xmlRootNode;
  182. try
  183. {
  184. XmlNode obj = table.SelectSingleNode(priKey);
  185. if (obj != null)
  186. {
  187. Dictionary<string, string> dic = new Dictionary<string, string>();
  188. for (int i = 0; i < obj.Attributes.Count; i++)
  189. {
  190. dic.Add(obj.Attributes[i].LocalName, obj.Attributes[i].Value);
  191. }
  192. t = ClazzFactory.ClazzPack<T>(dic);
  193. }
  194. }
  195. catch (Exception ex)
  196. {
  197. Close();
  198. UnityLog.LogError(priKey + ex.ToString());
  199. }
  200. return t;
  201. }
  202. public List<T> FindAllData<T>()
  203. {
  204. XmlNode table = xmlRootNode;
  205. if (table == null || table.ChildNodes.Count == 0)
  206. {
  207. return null;
  208. }
  209. List<T> list = new List<T>();
  210. for (int i = 0; i < table.ChildNodes.Count; i++)
  211. {//遍历表的子节点
  212. Dictionary<string, string> values = new Dictionary<string, string>();
  213. for (int j = 0; j < table.ChildNodes[i].Attributes.Count; j++)
  214. {
  215. values.Add(table.ChildNodes[i].Attributes[j].LocalName, table.ChildNodes[i].Attributes[j].Value);
  216. }
  217. list.Add(ClazzFactory.ClazzPack<T>(values));
  218. }
  219. return list;
  220. }
  221. public List<T> FindAllData<T>(string data)
  222. {
  223. return null;
  224. }
  225. /// <summary>
  226. /// 查找所有对象
  227. /// </summary>
  228. /// <typeparam name="T"></typeparam>
  229. /// <returns></returns>
  230. public List<T> FindAllData<T>(byte[] data)
  231. {
  232. try
  233. {
  234. xmlDoc = new XmlDocument();
  235. string xmlStr = UnityUtil.GetUTF8String(data);
  236. xmlDoc.LoadXml(xmlStr);
  237. tableName = typeof(T).Name;
  238. xmlRootNode = xmlDoc.SelectSingleNode(tableName);
  239. }
  240. catch (Exception ex)
  241. {
  242. UnityLog.LogError(ex.ToString());
  243. }
  244. return FindAllData<T>();
  245. }
  246. public bool UpdateData<T>(T data, string priKey)
  247. {
  248. Dictionary<string, string> field = ClazzFactory.ClazzAnalyze(data);
  249. if (field != null && field.Count > 0)
  250. {
  251. XmlNode table = xmlRootNode;
  252. if (string.IsNullOrEmpty(priKey))
  253. {
  254. foreach (var item in field)
  255. {
  256. priKey = item.Value;
  257. break;
  258. }
  259. }
  260. return UpdateData<T>(data, table, field, priKey);
  261. }
  262. return false;
  263. }
  264. private bool UpdateData<T>(T data, XmlNode table, Dictionary<string, string> field, string priKey)
  265. {
  266. try
  267. {
  268. XmlNode obj = table.SelectSingleNode(priKey);
  269. if (obj == null)
  270. {
  271. //待更新数据不存在,更新失败
  272. return false;
  273. }
  274. ///需要判断变量名是否发生了变化
  275. bool isChanged = false;
  276. if (obj.Attributes.Count != field.Count)
  277. {
  278. isChanged = true;
  279. }
  280. if (!isChanged)
  281. {
  282. int index = 0;
  283. foreach (var item in field)
  284. {
  285. ///变量名不一致
  286. if (obj.Attributes[index].LocalName != item.Key)
  287. {
  288. isChanged = true;
  289. break;
  290. }
  291. index++;
  292. }
  293. }
  294. if (isChanged)
  295. {
  296. if (DeleteData<T>(priKey))
  297. {
  298. return InsertData(data, priKey);
  299. }
  300. else
  301. {
  302. return false;
  303. }
  304. }
  305. else
  306. {
  307. foreach (var item in field)
  308. {
  309. if (obj.Attributes[item.Key].Value != item.Value)
  310. {
  311. obj.Attributes[item.Key].Value = item.Value;
  312. isChanged = true;
  313. }
  314. }
  315. }
  316. return isChanged;
  317. }
  318. catch (Exception ex)
  319. {
  320. UnityLog.LogError(data + " " + priKey + ex.ToString());
  321. Close();
  322. }
  323. return false;
  324. }
  325. public bool UpdateData<T>(T data)
  326. {
  327. return UpdateData<T>(data, null);
  328. }
  329. public bool DeleteData<T>(string key)
  330. {
  331. XmlNode table = xmlRootNode;
  332. try
  333. {
  334. XmlNode obj = table.SelectSingleNode(key);//按照key值确定元素对象
  335. if (obj == null)
  336. {
  337. return false;
  338. }
  339. obj.RemoveAll();
  340. table.RemoveChild(obj);
  341. return true;
  342. }
  343. catch (Exception ex)
  344. {
  345. UnityLog.LogError(ex.ToString());
  346. }
  347. return false;
  348. }
  349. public bool DeleteAllData<T>()
  350. {
  351. try
  352. {
  353. XmlNode table = xmlRootNode;
  354. table.RemoveAll();
  355. return true;
  356. }
  357. catch (Exception ex)
  358. {
  359. UnityLog.LogError(ex.ToString());
  360. }
  361. return false;
  362. }
  363. /// <summary>
  364. /// 建表
  365. /// </summary>
  366. /// <param name="tableName"></param>
  367. /// <returns></returns>
  368. public bool Create(string tableName)
  369. {
  370. try
  371. {
  372. FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate);
  373. if (xmlDoc == null)
  374. {
  375. xmlDoc = new XmlDocument();
  376. }
  377. this.tableName = Path.GetFileNameWithoutExtension(tableName);
  378. XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
  379. xmlRootNode = xmlDoc.CreateElement(this.tableName);
  380. xmlDoc.AppendChild(xmlDeclaration);
  381. xmlDoc.AppendChild(xmlRootNode);
  382. fs.Dispose();
  383. fs.Close();
  384. return xmlRootNode != null;
  385. }
  386. catch (Exception ex)
  387. {
  388. UnityLog.Log("Create Error" + this.tableName + ex.ToString());
  389. }
  390. return false;
  391. }
  392. public void Save()
  393. {
  394. if (xmlDoc != null && !string.IsNullOrEmpty(filePath))
  395. {
  396. try
  397. {
  398. xmlDoc.Save(filePath);
  399. }
  400. catch (Exception ex)
  401. {
  402. UnityLog.LogError(filePath + "\n" + ex.ToString());
  403. }
  404. }
  405. }
  406. }
  407. }