XML示例


/* * Author: shenjun */ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Xml; public class XML_Operation : MonoBehaviour { private static XML_Operation instance; public static XML_Operation Instance { get { return instance; } } string fileName = "Items.xml"; public string FilePath { get { return Application.streamingAssetsPath + "/" + fileName; } } public List<PackageItem> equips = new List<PackageItem>(); public List<PackageItem> items = new List<PackageItem>(); #region ContextMenuItem用法 [ContextMenuItem("ResetXML", "ResetXML")] // 给该字符串字段添加一个单独的右键菜单 并设置该菜单功能所调用的方法 [Multiline(4)] // 使字符串在检视面板显示成几行 public string SS = ""; void ResetXML() { SS = ""; } #endregion #region Debug [ContextMenuItem("Reset", "ResetEquipsLoaded")] public List<PackageItem> equipsLoaded = new List<PackageItem>(); [ContextMenuItem("Reset", "ResetItemsLoaded")] public List<PackageItem> itemsLoaded = new List<PackageItem>(); void ResetEquipsLoaded() { equipsLoaded.Clear(); } void ResetItemsLoaded() { itemsLoaded.Clear(); } void AppendTest() { // 1. 使用绝对路径的XPath // bool flag = AppendXML("/道具列表/装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 2. 开头是两个斜线表示文件中所有符合模式的元素都会被选出来,即使处于树中不同的层级也会被选出来。 // bool flag = AppendXML("//装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 3. 通配符 // bool flag = AppendXML("/*/装备", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 4. 使用方括号可以选择分支 下标从1开始 选择第一个节点 // bool flag = AppendXML("/道具列表/装备[1]", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 5. 选择最后一个节点 // bool flag = AppendXML("/道具列表/装备[last()]", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 6. 选择所有带有 倚天剑 元素并满足一定层次结构的装备节点 // bool flag = AppendXML("/道具列表/装备[倚天剑]", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 7. 选取 价格=1000的节点 // bool flag = AppendXML("/道具列表/装备/青铜剑[价格=1000]", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 8. 选取 符合一定层次结构的 装备和道具 节点 // bool flag = AppendXML("/道具列表/装备 | /道具列表/道具", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 9. 除了选择元素之外,也可以选择属性 属性都是以 @开头 这里表示选取所有id属性 // bool flag = AppendXML("//@id", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 10. 选取所有道具节点下 具有id属性的节点 // bool flag = AppendXML("//道具/*[@id]", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 11. 选取所有道具节点下 具有id属性 并且id属性等于12的节点 // bool flag = AppendXML("//道具/*[@id=12]", new PackageItem(){ id = "4", name = "铁剑", price = 500 }); // 12. 通过节点名查找 bool flag = AppendXML("大还丹", new PackageItem(){ id = "4", name = "铁剑", price = 500 }, true); if (!flag) Debug.Log("插入失败"); } void RemoveTest() { // bool flag = RemoveXML("//*[@id=12]"); // bool flag = RemoveXML("/道具列表/装备/倚天剑"); // bool flag = RemoveXML("/道具列表/装备/*[价格=1000]"); bool flag = RemoveXML("屠龙刀", true); if (!flag) Debug.Log("删除失败"); } void ModifyTest() { bool flag = ModifyXML("//*[@id=12]/价格", "2000"); if (!flag) { Debug.Log("修改失败"); } } void GetXMLNodeTest() { List<PackageItem> items; // items = GetXMLNode("//*[@id=11]"); items = GetXMLNode("青铜剑", true); foreach (var item in items) { Debug.Log("Name :" + item.name); Debug.Log("Id : " + item.id); Debug.Log("Price : " + item.price); } } #endregion void Awake() { instance = this; } void Start() { // AppendTest(); // RemoveTest(); // ModifyTest(); // GetXMLNodeTest(); } public List<PackageItem> GetXMLNode(string xpath, bool byTag = false) { if (!System.IO.File.Exists(FilePath)) return null; List<PackageItem> nodesList = new List<PackageItem>(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(FilePath); XmlNodeList nodes; if (byTag) { nodes = xmlDoc.GetElementsByTagName(xpath); } else { nodes = xmlDoc.SelectNodes(xpath); } foreach (XmlElement n in nodes) { PackageItem item = new PackageItem(); item.name = n.Name; if (n.HasAttribute("id")) { item.id = n.GetAttribute("id"); } if (n.HasChildNodes) { int.TryParse(n.FirstChild.InnerText, out item.price); } nodesList.Add(item); } return nodesList; } [ContextMenu("生成道具XML文件")] void CreateXML() { if (System.IO.File.Exists(FilePath)) { System.IO.File.Delete(FilePath); } XmlDocument xmlDoc = new XmlDocument(); XmlDeclaration xmlDec = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null); xmlDoc.AppendChild(xmlDec); // 只允许有一个根节点 XmlElement root = xmlDoc.CreateElement("道具列表"); if (equips.Count > 0) { XmlElement xmlEquip = xmlDoc.CreateElement("装备"); foreach (var item in equips) { XmlElement name = xmlDoc.CreateElement(item.name); name.SetAttribute("id", item.id); XmlElement price = xmlDoc.CreateElement("价格"); price.InnerText = item.price.ToString(); xmlEquip.AppendChild(name); name.AppendChild(price); } root.AppendChild(xmlEquip); } if (items.Count > 0) { XmlElement xmlItem = xmlDoc.CreateElement("道具"); foreach (var item in items) { XmlElement name = xmlDoc.CreateElement(item.name); name.SetAttribute("id", item.id); XmlElement price = xmlDoc.CreateElement("价格"); price.InnerText = item.price.ToString(); xmlItem.AppendChild(name); name.AppendChild(price); } root.AppendChild(xmlItem); } xmlDoc.AppendChild(root); xmlDoc.Save(FilePath); #if UNITY_EDITOR AssetDatabase.Refresh(); #endif } [ContextMenu("载入XML文件")] void LoadXML() { equipsLoaded.Clear(); itemsLoaded.Clear(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(FilePath); // XmlElement root = xmlDoc.DocumentElement; // Debug.Log("Root : " + root.Name); // XPath的开头是一个斜线代表这是绝对路径,可以选出所有路径符合这个模式的元素。 XmlNode node = xmlDoc.SelectSingleNode("/道具列表/装备"); XmlNodeList pNodeList = node.ChildNodes; foreach (var item in pNodeList) { XmlElement element = item as XmlElement; if (element != null) { PackageItem equip = new PackageItem(); equip.name = element.Name; equip.id = element.GetAttribute("id"); equip.price = int.Parse(element.InnerText); equipsLoaded.Add(equip); } } node = xmlDoc.SelectSingleNode("/道具列表/道具"); pNodeList = node.ChildNodes; foreach (var item in pNodeList) { XmlElement element = item as XmlElement; if (element != null) { PackageItem equip = new PackageItem(); equip.name = element.Name; equip.id = element.GetAttribute("id"); equip.price = int.Parse(element.InnerText); itemsLoaded.Add(equip); } } } public bool AppendXML(string xpath, PackageItem item, bool byTag = false) { if (!System.IO.File.Exists(FilePath)) return false; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(FilePath); XmlNodeList nodes; if (byTag) { nodes = xmlDoc.GetElementsByTagName(xpath); } else { nodes = xmlDoc.SelectNodes(xpath); } if (nodes == null || nodes.Count == 0) return false; // 测试第9点 获取所有满足条件的属性 // foreach (XmlAttribute n in nodes) // { // Debug.Log(n.Value); // Debug.Log(n.OwnerElement.Name); // } foreach (XmlElement node in nodes) { XmlElement name = xmlDoc.CreateElement(item.name); name.SetAttribute("id", item.id); XmlElement price = xmlDoc.CreateElement("价格"); price.InnerText = item.price.ToString(); name.AppendChild(price); node.AppendChild(name); } xmlDoc.Save(FilePath); // 保存 return true; } public bool RemoveXML(string xpath, bool byTag = false) { if (!System.IO.File.Exists(FilePath)) return false; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(FilePath); XmlNodeList nodes; if (byTag) { nodes = xmlDoc.GetElementsByTagName(xpath); } else { nodes = xmlDoc.SelectNodes(xpath); } if (nodes == null || nodes.Count == 0) return false; for (int i = 0; i < nodes.Count; i++) { Debug.Log("删除节点:" + nodes[i].Name); nodes[i].ParentNode.RemoveChild(nodes[i]); } xmlDoc.Save(FilePath); return true; } public bool ModifyXML(string xpath, string value) { if (!System.IO.File.Exists(FilePath)) return false; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(FilePath); XmlNodeList nodes = xmlDoc.SelectNodes(xpath); if (nodes == null || nodes.Count == 0) return false; foreach (XmlElement n in nodes) { n.InnerText = value; } xmlDoc.Save(FilePath); return true; } } [System.Serializable] public struct PackageItem { public string id; public string name; public int price; }