XML示例

 5.24 XML示例  - 图1

 5.24 XML示例  - 图2

  1. /*
  2. * Author: shenjun
  3. */
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using UnityEngine;
  7. using UnityEditor;
  8. using System.Xml;
  9. public class XML_Operation : MonoBehaviour
  10. {
  11. private static XML_Operation instance;
  12. public static XML_Operation Instance { get { return instance; } }
  13. string fileName = "Items.xml";
  14. public string FilePath { get { return Application.streamingAssetsPath + "/" + fileName; } }
  15. public List<PackageItem> equips = new List<PackageItem>();
  16. public List<PackageItem> items = new List<PackageItem>();
  17. #region ContextMenuItem用法
  18. [ContextMenuItem("ResetXML", "ResetXML")] // 给该字符串字段添加一个单独的右键菜单 并设置该菜单功能所调用的方法
  19. [Multiline(4)] // 使字符串在检视面板显示成几行
  20. public string SS = "";
  21. void ResetXML()
  22. {
  23. SS = "";
  24. }
  25. #endregion
  26. #region Debug
  27. [ContextMenuItem("Reset", "ResetEquipsLoaded")]
  28. public List<PackageItem> equipsLoaded = new List<PackageItem>();
  29. [ContextMenuItem("Reset", "ResetItemsLoaded")]
  30. public List<PackageItem> itemsLoaded = new List<PackageItem>();
  31. void ResetEquipsLoaded()
  32. {
  33. equipsLoaded.Clear();
  34. }
  35. void ResetItemsLoaded()
  36. {
  37. itemsLoaded.Clear();
  38. }
  39. void AppendTest()
  40. {
  41. // 1. 使用绝对路径的XPath
  42. // bool flag = AppendXML("/道具列表/装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  43. // 2. 开头是两个斜线表示文件中所有符合模式的元素都会被选出来,即使处于树中不同的层级也会被选出来。
  44. // bool flag = AppendXML("//装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  45. // 3. 通配符
  46. // bool flag = AppendXML("/*/装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  47. // 4. 使用方括号可以选择分支 下标从1开始 选择第一个节点
  48. // bool flag = AppendXML("/道具列表/装备[1]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  49. // 5. 选择最后一个节点
  50. // bool flag = AppendXML("/道具列表/装备[last()]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  51. // 6. 选择所有带有 倚天剑 元素并满足一定层次结构的装备节点
  52. // bool flag = AppendXML("/道具列表/装备[倚天剑]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  53. // 7. 选取 价格=1000的节点
  54. // bool flag = AppendXML("/道具列表/装备/青铜剑[价格=1000]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  55. // 8. 选取 符合一定层次结构的 装备和道具 节点
  56. // bool flag = AppendXML("/道具列表/装备 | /道具列表/道具", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  57. // 9. 除了选择元素之外,也可以选择属性 属性都是以 @开头 这里表示选取所有id属性
  58. // bool flag = AppendXML("//@id", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  59. // 10. 选取所有道具节点下 具有id属性的节点
  60. // bool flag = AppendXML("//道具/*[@id]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  61. // 11. 选取所有道具节点下 具有id属性 并且id属性等于12的节点
  62. // bool flag = AppendXML("//道具/*[@id=12]", new PackageItem(){ id = "4", name = "铁剑", price = 500 });
  63. // 12. 通过节点名查找
  64. bool flag = AppendXML("大还丹", new PackageItem(){ id = "4", name = "铁剑", price = 500 }, true);
  65. if (!flag)
  66. Debug.Log("插入失败");
  67. }
  68. void RemoveTest()
  69. {
  70. // bool flag = RemoveXML("//*[@id=12]");
  71. // bool flag = RemoveXML("/道具列表/装备/倚天剑");
  72. // bool flag = RemoveXML("/道具列表/装备/*[价格=1000]");
  73. bool flag = RemoveXML("屠龙刀", true);
  74. if (!flag)
  75. Debug.Log("删除失败");
  76. }
  77. void ModifyTest()
  78. {
  79. bool flag = ModifyXML("//*[@id=12]/价格", "2000");
  80. if (!flag)
  81. {
  82. Debug.Log("修改失败");
  83. }
  84. }
  85. void GetXMLNodeTest()
  86. {
  87. List<PackageItem> items;
  88. // items = GetXMLNode("//*[@id=11]");
  89. items = GetXMLNode("青铜剑", true);
  90. foreach (var item in items)
  91. {
  92. Debug.Log("Name :" + item.name);
  93. Debug.Log("Id : " + item.id);
  94. Debug.Log("Price : " + item.price);
  95. }
  96. }
  97. #endregion
  98. void Awake()
  99. {
  100. instance = this;
  101. }
  102. void Start()
  103. {
  104. // AppendTest();
  105. // RemoveTest();
  106. // ModifyTest();
  107. // GetXMLNodeTest();
  108. }
  109. public List<PackageItem> GetXMLNode(string xpath, bool byTag = false)
  110. {
  111. if (!System.IO.File.Exists(FilePath))
  112. return null;
  113. List<PackageItem> nodesList = new List<PackageItem>();
  114. XmlDocument xmlDoc = new XmlDocument();
  115. xmlDoc.Load(FilePath);
  116. XmlNodeList nodes;
  117. if (byTag)
  118. {
  119. nodes = xmlDoc.GetElementsByTagName(xpath);
  120. }
  121. else
  122. {
  123. nodes = xmlDoc.SelectNodes(xpath);
  124. }
  125. foreach (XmlElement n in nodes)
  126. {
  127. PackageItem item = new PackageItem();
  128. item.name = n.Name;
  129. if (n.HasAttribute("id"))
  130. {
  131. item.id = n.GetAttribute("id");
  132. }
  133. if (n.HasChildNodes)
  134. {
  135. int.TryParse(n.FirstChild.InnerText, out item.price);
  136. }
  137. nodesList.Add(item);
  138. }
  139. return nodesList;
  140. }
  141. [ContextMenu("生成道具XML文件")]
  142. void CreateXML()
  143. {
  144. if (System.IO.File.Exists(FilePath))
  145. {
  146. System.IO.File.Delete(FilePath);
  147. }
  148. XmlDocument xmlDoc = new XmlDocument();
  149. XmlDeclaration xmlDec = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
  150. xmlDoc.AppendChild(xmlDec);
  151. // 只允许有一个根节点
  152. XmlElement root = xmlDoc.CreateElement("道具列表");
  153. if (equips.Count > 0)
  154. {
  155. XmlElement xmlEquip = xmlDoc.CreateElement("装备");
  156. foreach (var item in equips)
  157. {
  158. XmlElement name = xmlDoc.CreateElement(item.name);
  159. name.SetAttribute("id", item.id);
  160. XmlElement price = xmlDoc.CreateElement("价格");
  161. price.InnerText = item.price.ToString();
  162. xmlEquip.AppendChild(name);
  163. name.AppendChild(price);
  164. }
  165. root.AppendChild(xmlEquip);
  166. }
  167. if (items.Count > 0)
  168. {
  169. XmlElement xmlItem = xmlDoc.CreateElement("道具");
  170. foreach (var item in items)
  171. {
  172. XmlElement name = xmlDoc.CreateElement(item.name);
  173. name.SetAttribute("id", item.id);
  174. XmlElement price = xmlDoc.CreateElement("价格");
  175. price.InnerText = item.price.ToString();
  176. xmlItem.AppendChild(name);
  177. name.AppendChild(price);
  178. }
  179. root.AppendChild(xmlItem);
  180. }
  181. xmlDoc.AppendChild(root);
  182. xmlDoc.Save(FilePath);
  183. #if UNITY_EDITOR
  184. AssetDatabase.Refresh();
  185. #endif
  186. }
  187. [ContextMenu("载入XML文件")]
  188. void LoadXML()
  189. {
  190. equipsLoaded.Clear();
  191. itemsLoaded.Clear();
  192. XmlDocument xmlDoc = new XmlDocument();
  193. xmlDoc.Load(FilePath);
  194. // XmlElement root = xmlDoc.DocumentElement;
  195. // Debug.Log("Root : " + root.Name);
  196. // XPath的开头是一个斜线代表这是绝对路径,可以选出所有路径符合这个模式的元素。
  197. XmlNode node = xmlDoc.SelectSingleNode("/道具列表/装备");
  198. XmlNodeList pNodeList = node.ChildNodes;
  199. foreach (var item in pNodeList)
  200. {
  201. XmlElement element = item as XmlElement;
  202. if (element != null)
  203. {
  204. PackageItem equip = new PackageItem();
  205. equip.name = element.Name;
  206. equip.id = element.GetAttribute("id");
  207. equip.price = int.Parse(element.InnerText);
  208. equipsLoaded.Add(equip);
  209. }
  210. }
  211. node = xmlDoc.SelectSingleNode("/道具列表/道具");
  212. pNodeList = node.ChildNodes;
  213. foreach (var item in pNodeList)
  214. {
  215. XmlElement element = item as XmlElement;
  216. if (element != null)
  217. {
  218. PackageItem equip = new PackageItem();
  219. equip.name = element.Name;
  220. equip.id = element.GetAttribute("id");
  221. equip.price = int.Parse(element.InnerText);
  222. itemsLoaded.Add(equip);
  223. }
  224. }
  225. }
  226. public bool AppendXML(string xpath, PackageItem item, bool byTag = false)
  227. {
  228. if (!System.IO.File.Exists(FilePath))
  229. return false;
  230. XmlDocument xmlDoc = new XmlDocument();
  231. xmlDoc.Load(FilePath);
  232. XmlNodeList nodes;
  233. if (byTag)
  234. {
  235. nodes = xmlDoc.GetElementsByTagName(xpath);
  236. }
  237. else
  238. {
  239. nodes = xmlDoc.SelectNodes(xpath);
  240. }
  241. if (nodes == null || nodes.Count == 0)
  242. return false;
  243. // 测试第9点 获取所有满足条件的属性
  244. // foreach (XmlAttribute n in nodes)
  245. // {
  246. // Debug.Log(n.Value);
  247. // Debug.Log(n.OwnerElement.Name);
  248. // }
  249. foreach (XmlElement node in nodes)
  250. {
  251. XmlElement name = xmlDoc.CreateElement(item.name);
  252. name.SetAttribute("id", item.id);
  253. XmlElement price = xmlDoc.CreateElement("价格");
  254. price.InnerText = item.price.ToString();
  255. name.AppendChild(price);
  256. node.AppendChild(name);
  257. }
  258. xmlDoc.Save(FilePath); // 保存
  259. return true;
  260. }
  261. public bool RemoveXML(string xpath, bool byTag = false)
  262. {
  263. if (!System.IO.File.Exists(FilePath))
  264. return false;
  265. XmlDocument xmlDoc = new XmlDocument();
  266. xmlDoc.Load(FilePath);
  267. XmlNodeList nodes;
  268. if (byTag)
  269. {
  270. nodes = xmlDoc.GetElementsByTagName(xpath);
  271. }
  272. else
  273. {
  274. nodes = xmlDoc.SelectNodes(xpath);
  275. }
  276. if (nodes == null || nodes.Count == 0)
  277. return false;
  278. for (int i = 0; i < nodes.Count; i++)
  279. {
  280. Debug.Log("删除节点:" + nodes[i].Name);
  281. nodes[i].ParentNode.RemoveChild(nodes[i]);
  282. }
  283. xmlDoc.Save(FilePath);
  284. return true;
  285. }
  286. public bool ModifyXML(string xpath, string value)
  287. {
  288. if (!System.IO.File.Exists(FilePath))
  289. return false;
  290. XmlDocument xmlDoc = new XmlDocument();
  291. xmlDoc.Load(FilePath);
  292. XmlNodeList nodes = xmlDoc.SelectNodes(xpath);
  293. if (nodes == null || nodes.Count == 0)
  294. return false;
  295. foreach (XmlElement n in nodes)
  296. {
  297. n.InnerText = value;
  298. }
  299. xmlDoc.Save(FilePath);
  300. return true;
  301. }
  302. }
  303. [System.Serializable]
  304. public struct PackageItem
  305. {
  306. public string id;
  307. public string name;
  308. public int price;
  309. }