C# xml格式化

    xiaoxiao2022-07-13  210

    using System;//From:www.uzhanbao.com using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; // 用于实现对xml文件测处理 namespace get_Manifest_txt { /// <summary> /// 属性, 形如: encoding="utf-8" /// </summary> public class attribute { public string name = "属性名"; public string value= "属性值"; public attribute(){} /// <summary> /// 创建属性 /// </summary> public attribute(string name, string value) { this.name = name; this.value = value; } /// <summary> /// 获取属性,的字符串形式 /// </summary> public string ToString() { return name + "=" + "\"" + value + "\""; } /// <summary> /// 从属性串创建属性, 形如:encoding="utf-8" 或 encoding=utf-8 /// </summary> public static attribute Parse(string attrStr) { attrStr = attrStr.Trim(); if (attrStr.Contains("=")) { attribute iteam = new attribute(); //string[] A = attrStr.Split('=');          // 按=分割属性名称和属性值 string[] A = xmlNode.split(attrStr, "="); // 仅分割为两个字符串 iteam.name = A[0].Trim(); iteam.value = A[1].Trim().Trim('"'); return iteam; } return null; } } /// <summary> /// 属性List, 形如: version="1.0" encoding="utf-8" standalone="no" ... /// 包含若干个属性 /// </summary> public class attributeList { public List<string> list = new List<string>(); // 属性列表,字符串形式 public Dictionary<string, string> dic = new Dictionary<string, string>(); // 属性字典,名称、值 public attributeList() { } /// <summary> /// 向属性list中添加新的属性 /// </summary> public void Add(attribute attr) { if (!dic.Keys.Contains(attr.name)) { dic.Add(attr.name, attr.value); list.Add(attr.ToString()); } } /// <summary> /// 向属性list中添加新的属性 /// </summary> public void Add(string name, string value) { Add(new attribute(name, value)); } /// <summary> /// 从属性list中移除指定的属性 /// </summary> public void Remove(attribute attr) { if (dic.Keys.Contains(attr.name)) { dic.Remove(attr.name); list.Remove(attr.ToString()); } } /// <summary> /// 从属性list中移除指定的属性,name为属性名 /// </summary> public void Remove(string name) { if (dic.Keys.Contains(name)) Remove(new attribute(name, dic[name])); } /// <summary> /// 清空属性list /// </summary> public void Clear() { list.Clear(); dic.Clear(); } /// <summary> /// 判断属性list中中是否含有属性attr /// </summary> public bool Contains(attribute attr) { return list.Contains(attr.ToString()); } /// <summary> /// 判断属性list中是否含有属性, name为属性名 /// </summary> public bool Contains(string name) { return dic.Keys.Contains(name); } /// <summary> /// 判断属性list中是否含有属性值, value为属性值 /// </summary> public bool ContainsValue(string value) { return dic.Values.Contains(value); //foreach (string V in dic.Values) //{ //    if (V.Contains("=\"" + value + "\"")) //        return true; //} //return false; } ///<summary> /// 获取属性list的第index个属性 ///</summary> public attribute Get(int index) { if (index < list.Count) return attribute.Parse(list[index]); return null; } ///<summary> /// 获取属性list中,属性名为name的属性值 ///</summary> public string Get(string name) { if (dic.Keys.Contains(name)) return dic[name]; return null; } /// <summary> /// 重新设置属性list中,属性名为name的属性值 /// 当value为ATTR_NULL时,仅清除节点属性 /// </summary> public void Set(string name, string value) { Remove(name); // 移除原有的属性 if(!value.Equals("ATTR_NULL")) Add(name, value); // 重新添加新的属性 } /// <summary> /// 重新设置属性list中,属性attr /// </summary> public void Set(attribute attr) { Remove(attr.name); // 移除原有的属性 Add(attr.name, attr.value); // 重新添加新的属性 } /// <summary> /// 重新设置属性List对应的所有属性 /// </summary> public void Set(attributeList List) { foreach (String name in List.dic.Keys) { Set(name, List.dic[name]); } } /// <summary> /// 获取属性list中的元素数目 /// </summary> public int Count() { return list.Count; } /// <summary> /// 获取属性list的字符串形式, /// 形如:version="1.0" encoding="utf-8" standalone="no" /// </summary> public string ToString() { string str = ""; foreach (string attr in list) str += (str.Equals("") ? "" : " ") + attr; return str; } /// <summary> /// 获取属性list经排序后的 字符串形式 /// 形如:version="1.0" encoding="utf-8" standalone="no" /// </summary> public string SortString() { attributeList attr = this.Clone(); attr.list.Sort(); // 元素排序 return attr.ToString(); } /// <summary> /// 从属性串创建属性list,  /// 形如:version="1.0" encoding="utf-8" standalone="no" /// 或:version=1.0 encoding=utf-8 standalone=no /// </summary> public static attributeList Parse(string Str) { if (Str.Contains("=")) { attributeList L = new attributeList(); //Str = Str.Trim(); //string[] A = Str.Split('\"'); //for (int i = 0; i < A.Length-1; i += 2) //    L.Add(new attribute(A[i].Trim().Trim('='), A[i + 1])); Str = Str.Trim().Replace("\r", " ").Replace("\n", " ").Replace("\t", " "); //while (Str.Contains("  ")) Str = Str.Replace("  ", " "); //string[] A = Str.Split(' '); string[] A = SplitAttrs(Str); for (int i = 0; i < A.Length; i ++) L.Add(attribute.Parse(A[i])); return L; } else return new attributeList(); } // 分割属性字符串,如:android:exported="false" android:label="Omlet Network Service" android:name="mobisocial.omlib.service.OmlibService" private static string[] SplitAttrs(String attrStr) { int S = 0, E = 0; List<String> list = new List<string>(); String reminder = attrStr; while (reminder.Contains("\"")) { S = reminder.IndexOf("\""); E = reminder.IndexOf("\"", S + 1); if(E > S) { list.Add(reminder.Substring(0, E)); reminder = reminder.Substring(E+1).Trim(); } } // 非标准形式的属性串,如:package=com.joym.limitkart.baidu 的解析 reminder = reminder.Trim(); if (!reminder.Equals("")) { while (reminder.Contains("  ")) reminder = reminder.Replace("  ", " "); string[] A = reminder.Split(' '); foreach (String str in A) list.Add(str); } return list.ToArray(); } /// <summary> /// 复制当前attributeList /// </summary> public attributeList Clone() { attributeList L = new attributeList(); foreach (string attr in list) L.Add(attribute.Parse(attr)); return L; } /// <summary> /// 判断两个属性list,是否具有相同的属性; /// 是否完全相同根据ToString()后串进行判定 /// </summary> public bool Equals(attributeList attributes) { if (this != null && attributes != null) { bool isMin1 = this.Count() <= attributes.Count(); attributeList min = isMin1 ? this : attributes; attributeList max = isMin1 ? attributes : this; foreach (string attribute in min.list) if (!max.list.Contains(attribute)) return false; // 存在不相同的属性 } return true; // 现有属性均相同 } /// <summary> /// 创建一个attributeList合集, /// 先添加attributes1中的所有属性,再添加仅存在attributes2中的属性 /// </summary> public static attributeList operator +(attributeList attributes1, attributeList attributes2) { attributeList L = attributes1.Clone(); foreach (string attr in attributes2.list) L.Add(attribute.Parse(attr)); return L; } } /// <summary> /// xml节点 /// </summary> public class xmlNode { public string name = "节点名"; public attributeList attributes = new attributeList(); // 节点属性 public string value = "节点值"; public List<xmlNode> childs = new List<xmlNode>(); // 子节点 public bool isDeclarNode = false; // 是否为xml的信息声明节点 <?xml version="1.0" encoding="utf-8" standalone="no"?> public xmlNode parent; // 父节点 public Dictionary<string, xmlNode> dic = new Dictionary<string, xmlNode>(); // 子节点特征串, 到子节点的映射表 public List<string> childNames = new List<string>(); // 存储子节点的节点名列表 public string note = ""; // 节点的注释说明信息 /// <summary> /// 创建xml节点 /// </summary> public xmlNode() { } /// <summary> /// 创建xml节点 /// </summary> public xmlNode(string name, attributeList attributes = null, string value = "", List<xmlNode> childs=null)  { this.name = name; if(attributes != null) this.attributes = attributes.Clone(); this.value = value; this.Add(childs); } /// <summary> /// 定义节点的特征串,为名称和节点属性值组合 /// </summary> public string Key() { string attrs = attributes.ToString(); return name + (attrs.Equals("") ? "" : " ") + attrs; } /// <summary> /// 定义节点的特征串,为名称和节点属性值组合 /// </summary> public string SortKey() { string attrs = attributes.SortString(); return name + (attrs.Equals("") ? "" : " ") + attrs; } /// <summary> /// 获取当前节点在父节点中的路径信息 /// </summary> public string Path() { if (parent != null) return parent.Path() + "/" + this.name; else return this.name; } /// <summary> /// 添加新的子节点到当前节点 /// </summary> public void Add(xmlNode child) { xmlNode node = child.getSameNode(this); // 在当前节点的子节点中查找与child相似的节点 if (node == null) { //添加子节点 childs.Add(child); child.parent = this; // 子节点相关信息记录 if (!dic.Keys.Contains(child.SortKey())) dic.Add(child.SortKey(), child); if (!childNames.Contains(child.name)) childNames.Add(child.name); } else { // 将child节点的属性和其子节点,合并到查找到的相似的子节点中 node.Combine(child); } } /// <summary> /// 添加list的所有节点到当前节点的子节点集合中 /// </summary> public void Add(List<xmlNode> list) { if (list != null) { foreach (xmlNode child in list) this.Add(child.Clone()); } } /// <summary> /// 将节点node的属性和子节点合并到当前节点中 /// </summary> public void Combine(xmlNode node) { // 添加node中的属性到当前节点中 this.attributes = this.attributes + node.attributes; // 添加node的所有子节点到当前节点中 this.Add(node.childs); } /// <summary> /// 将两List xmlNode 合并为一个list, 将listSource添加到listTarget上 /// </summary> public static List<xmlNode> Combine(List<xmlNode> listTarget, List<xmlNode> listSource) { xmlNode N = new xmlNode(); N.Add(listTarget); N.Add(listSource); // 清除childs的父节点信息 foreach (xmlNode child in N.childs) child.parent = null; return N.childs; } /// <summary> /// 将两个Manifest.xml合并,将listSource添加到listTarget上 /// 合并"manifest", "application"节点,保留所有activity等待后续操作 /// </summary> public static List<xmlNode> CombineManifest(List<xmlNode> listTarget, List<xmlNode> listSource) { xmlNode N = new xmlNode(); N.Add(listTarget); N.Add(listSource); string[] combinePath = { "manifest", "application"/*, "activity"*/ }; xmlNode T = N; foreach (string name in combinePath) { // 合并所有manifest到第一个中 List<xmlNode> list = T.GetChilds(name); if (name.Equals("activity")) list = getLancherActivity(list); // 获取入口Activity for (int i = 1; i < list.Count; i++) { if (name.Equals("activity")) // 移除入口Activity中原有的intent-filter节点 list[0].Remove(list[0].Get("intent-filter")); list[0].Combine(list[i]); T.Remove(list[i]); } T = list[0]; } // 清除childs的父节点信息 foreach (xmlNode child in N.childs) child.parent = null; return N.childs; } /// <summary> /// 获取list中,所有节点名为NodeName的节点 ///  /// 如:activity 或 activity:com.game.main /// </summary> public static List<xmlNode> getNodes(List<xmlNode> list, String NodeName) { xmlNode N = new xmlNode(); N.Add(list); List<xmlNode> list2 = N.GetChilds(NodeName); return list2; } /// <summary> /// 获取所有list中所有入口Activity /// </summary> public static List<xmlNode> getLancherActivity(List<xmlNode> list) { List<xmlNode> L = new List<xmlNode>(); foreach (xmlNode N in list) if (N.isLauncherActivity()) L.Add(N); return L; } /// <summary> /// 判断当前节点是否是入口Activity /// </summary> public bool isLauncherActivity() { if (!this.name.Equals("activity") || !childNames.Contains("intent-filter")) return false; else { xmlNode main = this.Get("intent-filter"); if (main != null && main.Contains("category android:name=\"android.intent.category.LAUNCHER\"")) return true; } return false; } /// <summary> /// 从当前节点中移除子节点 /// </summary> public void Remove(xmlNode child) { if (childs == null) childs = new List<xmlNode>(); if (Contains(child)) { childs.Remove(child); child.parent = null; dic.Remove(child.SortKey()); } } /// <summary> /// 判断当前节点中, 是否含有子节点child /// </summary> public bool Contains(xmlNode child) { return dic.Keys.Contains(child.SortKey()); } /// <summary> /// 判断当前节点中, 是否含有特征串为key的子节点 /// </summary> public bool Contains(string key) { // 解析Key()串 string[] A = Parse_Key(key); xmlNode Node = new xmlNode(A[0], attributeList.Parse(A[1])); return dic.Keys.Contains(Node.SortKey()); } /// <summary> /// 根据子节点的特征串,获取对应的子节点 /// </summary> public xmlNode Get(string key) { // 解析Key()串 string[] A = Parse_Key(key); xmlNode Node = new xmlNode(A[0], attributeList.Parse(A[1])); key = Node.SortKey(); if (Contains(key)) return dic[key]; else return null; } /// <summary> /// 根据子节点名,获取节点名对应的所有子节点; /// 若节点名为空则获取到的为当前节点 /// 如:activity 或 activity:com.game.main /// </summary> public List<xmlNode> GetChilds(string name) { string[] A = name.Split(':'); List<xmlNode> L = new List<xmlNode>(); if (name.Equals("")) L.Add(this); else { if (childNames.Contains(A[0])) { foreach (xmlNode child in childs) if (child.name.Equals(A[0])) L.Add(child); } // 记录所有含有属性值:X的节点 if (A.Length > 1 && !A[1].Equals("")) { List<xmlNode> L2 = new List<xmlNode>(); foreach (xmlNode N in L) { if (N.attributes.ContainsValue(A[1])) { L2.Add(N); } } L = L2; } } return L; } /// <summary> /// 根据子节点路径信息获取指定的子节点 /// 如:获取指定activity下的指定intent-filter节点 /// manifest/application/activity:com.game.main/intent-filter:lenovoid.MAIN ///  /// 或者创建 NEWNODE=<action android:name="android.intent.action.MAIN"/>形式的节点 /// THIS或空串返回当前节点 /// </summary> public xmlNode GetChild_ByPath(string path) { if (path.StartsWith("NEWNODE") && path.Contains("=")) { String New = path.Substring(path.IndexOf("=") + 1).Trim().Trim('"'); List<xmlNode> list = xmlNode.Parse(New); if (list.Count > 0) return list[0]; } else if (path.Equals("THIS")) return this; xmlNode N = this; string[] A = path.Split('/'); foreach (string P in A) { List<xmlNode> L = N.GetChilds(P); if (L.Count > 0) N = L[0]; else return null; } return N; } /// <summary> /// 合并节点, sourcePath到targetPath的子节点; /// 添加source节点的属性和子节点到target节点,若target已有某条属性则不变,没有则添加 ///  /// 或添加节点sourcePath到targetPath, targetPath需以"/CHILDS"结尾 /// </summary> public void Add(string sourcePath, string targetPath) { xmlNode source = this.GetChild_ByPath(sourcePath); bool addchils = targetPath.EndsWith("/CHILDS"); if(addchils) { targetPath = targetPath.Substring(0, targetPath.LastIndexOf("/CHILDS")); } xmlNode target = this.GetChild_ByPath(targetPath); if (source == null || target == null) return; // 添加source节点的属性和子节点到target节点 if (addchils) target.childs.Add(source); else target.Combine(source); } /// <summary> /// 替换节点, /// 添加source节点的属性和子节点到target节点,若target已有某条属性则不变,没有则添加 /// </summary> public void Replace(string targetPath, string sourcePath) { xmlNode source = this.GetChild_ByPath(sourcePath); xmlNode target = this.GetChild_ByPath(targetPath); if (source == null || target == null) return; // 替换节点 xmlNode parent = target.parent; if (parent != null) { parent.Remove(target); parent.Add(source.Clone()); } } /// <summary> /// 设置path对应节点的属性值为attributeStr或attributeListStr /// 形如:version="1.0" encoding="utf-8" standalone="no" /// 或:version=1.0 encoding=utf-8 standalone=no /// </summary> public void SetAttribute(string path, string attributeStr) { xmlNode N = this.GetChild_ByPath(path); attributeList attrs = attributeList.Parse(attributeStr); if (N != null && attrs != null) N.attributes.Set(attrs); } /// <summary> /// 删除节点, nodePath对应的节点 /// 或者删除nodePath的所有子节点,nodePath需以/CHILDS结尾 /// </summary> public void Remove(string nodePath) { bool removeChils = nodePath.EndsWith("/CHILDS"); if (nodePath.EndsWith("/CHILDS")) nodePath = nodePath.Substring(0, nodePath.LastIndexOf("/CHILDS")); xmlNode node = this.GetChild_ByPath(nodePath); if (node != null) { if (removeChils) node.childs.Clear(); else { if (node.parent != null) node.parent.Remove(node); } } } /// <summary> /// 判断当前节点和node,是否为具有相同名称 和 属性list /// </summary> public bool Equals(xmlNode node) { if (this == null || node == null) return false; if (!this.name.Equals(node.name)) return false; // 名称不相同 if (!this.attributes.Equals(node.attributes)) return false; // 属性不相同 return true; } /// <summary> /// 获取root的子节点中,与当前节点具有相同名称和属性的节点 /// 重合的节点属性均相同,但Key()可能不同 /// </summary> public xmlNode getSameNode(xmlNode root) { if (root != null) { if (this.attributes.Count() == 0 && this.childs.Count == 0 && !this.value.Equals("")) return null; // 没有属性,没有子节点,仅有value值时,视作没有相同节点 else { if (root.dic.Keys.Contains(SortKey())) return root.dic[SortKey()]; foreach (xmlNode child in root.childs) if (child.Equals(this)) return child; } } return null; } /// <summary> /// 从当前节点复制出一个新的节点 /// </summary> public xmlNode Clone() { xmlNode N = new xmlNode(); N.name = this.name; N.value = this.value; N.attributes = this.attributes.Clone(); N.Add(this.childs); N.isDeclarNode = this.isDeclarNode; N.note = this.note; return N; } /// <summary> /// 定义xmlNode合并逻辑,从node1、和node2创建一个新的节点 /// </summary> public static xmlNode operator +(xmlNode node1, xmlNode node2) { xmlNode N = node1.Clone(); N.Combine(node2); return N; } /// <summary> /// 获取当前xmlNode的层次信息,检索parent直到为null的次数 /// </summary> public int Layer() { int i = 0; xmlNode N = this; while (N.parent != null) { N = N.parent; i++; } return i; } /// <summary> /// 获取当前节点的输出为字符串时,需要缩进的空格数 /// </summary> private string Space() { int layer = Layer(); string tabs = ""; while (layer-- > 0) tabs += "    "; // tabs += "\t"; return tabs; } /// <summary> /// 定义xmlNode的字符串形式 /// </summary> public string ToString() { // 是否为xml声明信息 if (isDeclarNode) return "<?" + Key() + "?>"; string space = Space(); string str = space + "<" + Key(); // 有子节点时的显示样式 if (childs.Count > 0) { str += ">"; foreach (xmlNode child in childs) str += "\r\n" + child.ToString(); str += "\r\n" + space + "</" + name + ">"; } // 有值时的显示样式 else if (!value.Equals("")) { str += ">" + value + "</" + name + ">"; } // 其余显示样式 else str += "/>"; // 添加当前节点的注释信息 if (!note.Equals("")) str = space + note + "\r\n" + str; return str; } /// <summary> /// 转化list为字符串形式 /// </summary> public static string ToString(List<xmlNode> list) { string Str = ""; bool haveDeclar = false; foreach (xmlNode node in list) { Str += (Str.Equals("") ? "" : "\r\n") + node.ToString(); if (node.isDeclarNode == true) haveDeclar = true; } string declar = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"; Str = (!haveDeclar ? declar : "") + Str; return Str; } /// <summary> /// 从字符串形式的xml节点,构建xmlNode /// </summary> public static xmlNode ParseOne(string Str) { List<xmlNode> L = Parse(Str); if (L.Count > 0) return L[0]; else return null; } /// <summary> /// 从字符串形式的xml节点,构建xmlNode /// </summary> public static List<xmlNode> Parse(string Str) { List<xmlNode> list = new List<xmlNode>(); string reminds = ""; string noteInfo = ""; while (!(Str = Str.Trim()).Equals("")) { try { int S = Str.IndexOf("<") + 1, E = Str.IndexOf(">", S); String key = Str.Substring(S, E - S); reminds = Str.Substring(E + 1); // 记录剩余未解析的串 // 注释信息不解析 if (key.StartsWith("!--")) { E = Str.IndexOf("-->", S); S = S - 1; // 获取节点注释信息 noteInfo = Str.Substring(S, E - S + "-->".Length); // 剔除注释信息 Str = Str.Substring(E + "-->".Length); continue; } bool isDeclear = key.StartsWith("?"); // 判定是否为xml声明节点 if (isDeclear) key = key.Trim('?'); string[] A = Parse_Key(key); // 解析Key()串 // 创建xmlNode对象 xmlNode Node = new xmlNode(A[0], attributeList.Parse(A[1])); Node.isDeclarNode = isDeclear; bool haveChildValue = (!isDeclear && !key.EndsWith("/")); // 判断是否有子节点或值 if (haveChildValue) { //int E2 = Str.IndexOf("</" + A[0], E); int E2 = getMatchIndex(Str, A[0]); // 获取与A[0]匹配的/A[0]在Str中的索引位置 string ValueStr = Str.Substring(E + 1, E2 - E - 1); E2 = Str.IndexOf(">", E2 + 1); reminds = Str.Substring(E2 + 1); // 记录剩余未解析的串 // 含有子节点,进行子节点的解析 //if (ValueStr.StartsWith("\"") && ValueStr.EndsWith("\"")) Node.value = ValueStr;    // 以引号开头和结尾的为节点值 //else { String ValueStrTmp = ValueStr.Trim(); if (ValueStrTmp.StartsWith("<") && ValueStrTmp.EndsWith(">") && ValueStrTmp.Contains("/")) { List<xmlNode> childs = Parse(ValueStr); Node.Add(childs); } // 有节点值  else Node.value = ValueStr; } } // 为当前节点添加注释信息 if (!noteInfo.Equals("")) { Node.note = noteInfo; noteInfo = ""; } list.Add(Node); Str = reminds; } catch (Exception ex) { DialogResult result = MessageBox.Show("解析" + Str + "时异常!", "是否查看?", MessageBoxButtons.OKCancel); if (result == DialogResult.OK) { String path = AppDomain.CurrentDomain.BaseDirectory + "xmlNode解析异常.txt"; if (File.Exists(path)) File.Delete(path); FileProcess.SaveProcess(Str, path); System.Diagnostics.Process.Start(path); } break; } } return list; } //<LinearLayout> //    <RelativeLayout>ssss3</RelativeLayout> //    <LinearLayout >ssss1</LinearLayout> //    <LinearLayout>ssss2</LinearLayout> //    <LinearLayout><TextView/></LinearLayout> //</LinearLayout> // 获取与首个<key >匹配的</key >索引位置 private static int getMatchIndex(string data, string key) { int index = -1; int pos = 0; string keyStr = ""; int count = 0; do { keyStr = getKeyStr(data, key, pos); // <key > 或 </key >对应串 index = data.IndexOf(keyStr, pos); // 获取索引位置 pos = index + keyStr.Length; // 记录检索位置 if (keyStr.StartsWith("</")) count--; else if (keyStr.StartsWith("<") && !keyStr.EndsWith("/>")) count++; // 累计匹配值 if (keyStr.Equals("")) return -1; } while (count != 0); string reminds = data.Substring(index, data.Length - index); return index; } // 从坐标S0处开始,获取<key > 或 </key >标识的串 private static string getKeyStr(string data, string key, int S0) { string str = getNodeString(data, key, S0); // 获取<key >节点串 string str2 = getNodeString(data, "/" + key, S0); // 获取</key >节点串 if (!str2.Equals("")) { if (str.Equals("")) str = str2; else { int index1 = data.IndexOf(str, S0); int index2 = data.IndexOf(str2, S0); if (index2 < index1) str = str2; // 取<key >或</key >靠前的那个 } } return str; } // 从data中获取第一个以<key ***>标识的串 private static string getNodeString(string data, string key, int S0) { if (data.Contains("<" + key) && data.Contains(">")) { int S = data.IndexOf("<" + key, S0); if (S != -1) { int E = data.IndexOf(">", S + key.Length + 1); if (E > S) return data.Substring(S, E - S + 1); } } return ""; } /// <summary> /// 解析Key()串, 形如:xml encoding="utf-8" /// </summary> private static string[] Parse_Key(string key) { string key0 = key.Trim().Trim('/'); key = key0.Replace("\r", " ").Replace("\t", " ").Replace("\n", " "); int S = key.IndexOf(" "); if (S == -1) return new string[] { key0, "" }; else { string name = key.Substring(0, S); string attrs = key.Substring(S + 1).Trim(); return new string[] { name, attrs }; } } /// <summary> /// 判断node1和node2,是否完全相同 /// 具有相同的节点名、节点属性、节点属性、子节点 /// </summary> //public static bool Equals(xmlNode node1, xmlNode node2) //{ //    if (node1 != node2) return false; //} /// <summary> /// 将两个xml文件,按节点属性名自动合并为同一个xml /// </summary> public static List<xmlNode> Combine(string xmlSource, string xmlTarget, bool isManifest) { List<xmlNode> listTarget = xmlNode.Parse(xmlTarget); List<xmlNode> listSource = xmlNode.Parse(xmlSource); List<xmlNode> list = !isManifest ? xmlNode.Combine(listTarget, listSource) : xmlNode.CombineManifest(listTarget, listSource); return list; //string xml = xmlNode.ToString(list); //return xml; } /// <summary> /// 获取manifests中的包名信息, manifest_File为 AndroidManifest.xml文件的完整路径 /// </summary> public static string getPackageName(string manifest_File) { string xmlTarget = FileProcess.fileToString(manifest_File); if (xmlTarget.Equals("")) return ""; List<xmlNode> listTarget = xmlNode.Parse(xmlTarget); List<xmlNode> gameManifests = getNodes(listTarget, "manifest"); // 获取manifest节点 String packageName = getPackageName(gameManifests); // 获取游戏包名信息 return packageName; } // 获取manifests中的包名信息 private static string getPackageName(List<xmlNode> manifests) { if(manifests.Count > 0 ) { xmlNode manifest = manifests[0]; attributeList attrs = manifest.attributes; if(attrs != null && attrs.Contains("package")) return attrs.Get("package"); } return ""; } /// <summary> /// 从文件中载入xml文件, 先复制FileTarget,在添加FileSource,输出到outFile /// </summary> public static void Combine(string FileSource, string FileTarget, string outFile, bool isManifest, List<string> cmds) { string xmlTarget = FileProcess.fileToString(FileTarget); string xmlSource = FileProcess.fileToString(FileSource); //string xml = xmlNode.Combine(xml1, xml2, isManifest); //FileProcess.SaveProcess(xml, outFile); List<xmlNode> list = xmlNode.Combine(xmlSource, xmlTarget, isManifest); // 执行Manifest简单混合 string xml = xmlNode.ToString(list); FileProcess.SaveProcess(xml, outFile); // 保存文件 //Manifest manifest = new Manifest(list, outFile);                // 创建Manifest对象 FileProcess.SaveProcess(xmlNode.ToString(list), outFile.Replace(".xml", "_缓存.xml")); 执行manifest修改逻辑 string[] cmd = { "remove GAME_MAIN_ACTIVITY/intent-filter", "add THIS_MAIN_ACTIVITY to GAME_MAIN_ACTIVITY" };   // 执行操作移除游戏入口Activity中的intent-filter,混合附加入口Activity string[] cmd = { "remove GAME_MAIN_ACTIVITY/intent-filter", "add activity:com.ltsdk_entryDemo.LogoActivity to GAME_MAIN_ACTIVITY", "remove activity:com.ltsdk_entryDemo.LogoActivity" }; //if (isManifest) //{ //    // 执行manifest处理逻辑 //    manifest.runCMD(cmds); //    // 获取游戏图标名称,如: @drawable/icon //    Settings.gameIcon = manifest.icon; //} 保存manifest //manifest.save(); } 自定义cmd处理命令逻辑 /// <summary> /// 执行多条操作 /// </summary> public void runCMD(List<string> cmds) { if (cmds != null && cmds.Count > 0) runCMD(cmds.ToArray()); } /// <summary> /// 执行多条操作 /// </summary> public void runCMD(string[] cmds) { foreach (string cmd in cmds) { try { runCMD(cmd); } catch (Exception ex) { MessageBox.Show(Path() + ".runCMD()报错:" + cmd + "\r\n" + ex.Message); } } } /// <summary> /// 自定Manifest处理逻辑 /// path (形如 manifest/application/activity:com.shjc.jsbc.Main),也可定义path为创建新的节点,NEWNODE=<action android:name="android.intent.action.MAIN"/> /// add path1 to path2      (添加path1对应的节点信息到path2) /// replace path1 by path2  () /// remove path             (删除path处的节点) /// get path set attr       (获取指定的节点,并修改其属性值attr) /// GAME_MAIN_ACTIVITY      (指代游戏入口Activity Path) /// THIS_MAIN_ACTIVITY      (指代当前配置计费包apk的Activity Path) /// </summary> public void runCMD(string cmd) { // 移除指定的节点 if (cmd.StartsWith("remove ")) { string path = cmd.Substring("remove ".Length); Remove(path); } else if (cmd.StartsWith("get ")) { cmd = cmd.Substring("get ".Length).Trim(); string[] A = split(cmd, " set "); if (A.Length > 1) SetAttribute(A[0], A[1]); } else if (cmd.StartsWith("add ")) { cmd = cmd.Substring("add ".Length).Trim(); string[] A = split(cmd, " to "); if (A.Length > 1) Add(A[0], A[1]); } else if (cmd.StartsWith("replace ")) { cmd = cmd.Substring("replace ".Length).Trim(); string[] A = split(cmd, " by "); if (A.Length > 1) Replace(A[0], A[1]); } } /// <summary> /// 将data按seprator分割为两个子串 /// </summary> public static string[] split(string data, string seprator) { if (data.Contains(seprator)) { int S = data.IndexOf(seprator), E = S + seprator.Length; string[] A = new string[2]; A[0] = data.Substring(0, S).Trim(); A[1] = data.Substring(E).Trim(); return A; } else return new string[] { data }; } } /// <summary> /// 定义Manifest用于修改Manifest.xml /// </summary> public class Manifest { //public static Cmd.Callback call; // 基础数据 string filePath = ""; public List<xmlNode> list; // 拓展信息 public xmlNode manifest; public xmlNode application; public xmlNode LauncherActivity;// 启动Activity public string applicationName; // 应用包名 public string icon; // icon图标属性值 List<xmlNode> permissions; List<xmlNode> activitys; List<xmlNode> services; List<xmlNode> meta_datas; List<xmlNode> receivers; string GAME_MAIN_ACTIVITY; // 指代Manifest.xml第一个MAIN_ACTIVITY路径 string THIS_MAIN_ACTIVITY; // 指代Manifest.xml第二个MAIN_ACTIVITY路径 string MANIFEST = " "; // 指代manifest节点 Dictionary<string, xmlNode> ActivityDic = new Dictionary<string, xmlNode>(); public Manifest(string filePath) { this.filePath = filePath; string xml = FileProcess.fileToString(filePath); list = xmlNode.Parse(xml); InitLoad(); } public Manifest(string xml, string filePath) { this.filePath = filePath; list = xmlNode.Parse(xml); InitLoad(); } public Manifest(List<xmlNode> list, string filePath) { this.filePath = filePath; this.list = list; InitLoad(); } /// <summary> /// 初始载入,预处理 /// </summary> private void InitLoad() { if (!(list.Count > 1 || !list[1].name.Equals("manifest"))) return; manifest = list[1]; List<xmlNode> L = manifest.GetChilds("application"); if (L.Count == 0) return; application = L[0]; permissions = manifest.GetChilds("uses-permission"); if (application == null) return; activitys = application.GetChilds("activity"); services = application.GetChilds("service"); meta_datas = application.GetChilds("meta-data"); receivers = application.GetChilds("receiver"); if (application.attributes != null) { applicationName = application.attributes.Get("android:name"); icon = application.attributes.Get("android:icon"); } // 获取activitys中所有入口Activity L = xmlNode.getLancherActivity(activitys); if (L.Count == 0) return; LauncherActivity = L[0]; // 获取第一个入口Activity路径 string name1 = L[0].attributes.Get("android:name"); GAME_MAIN_ACTIVITY = "activity:" + name1; if (L.Count > 1) { // 获取第一个入口Activity路径 string name2 = L[1].attributes.Get("android:name"); THIS_MAIN_ACTIVITY = "activity:" + name2; } else THIS_MAIN_ACTIVITY = ""; } /// <summary> /// 已Activity的名称为键值,构建映射表 /// </summary> private void createDic(List<xmlNode> activitys) { //<activity android:name="com.shjc.jsbc.view2d.selectmap.SelectMap" android:screenOrientation="landscape"/> foreach (xmlNode N in activitys) { if (N.attributes != null) { string activityName = N.attributes.Get("android:name"); if(!ActivityDic.Keys.Contains(activityName)) ActivityDic.Add(activityName, N); } } } /// <summary> /// 保存到文件 /// </summary> public void save() { string xml = xmlNode.ToString(list); FileProcess.SaveProcess(xml, filePath); } /// <summary> /// 设置应用包名 /// </summary> public void setApplicationName(string name) { if (application != null || application.attributes != null) { application.attributes.Set("android:name", name); } } /// <summary> /// 获取对应名称的Activity节点, 如:com.shjc.jsbc.Main /// </summary> public xmlNode getActivity(string name) { if (ActivityDic.Keys.Contains(name)) return ActivityDic[name]; else return null; } /// <summary> /// 根节点manifest /// 获取path对应的节点 ///  /// 如:  /// uses-permission:android.permission.SEND_SMS ///  /// application/activity:com.shjc.jsbc.Main 或 /// activity:com.shjc.jsbc.Main /// service:com.lenovo.AppCheckService /// meta-data:lenovo.gamesdk.new /// receiver:com.lenovo.lsf.push.receiver.PushReceiver /// </summary> private string FullPath(string path) { if (path.Contains("GAME_MAIN_ACTIVITY")) path = path.Replace("GAME_MAIN_ACTIVITY", GAME_MAIN_ACTIVITY); // 替换字段为游戏入口Activity路径 if (path.Contains("THIS_MAIN_ACTIVITY")) path = path.Replace("THIS_MAIN_ACTIVITY", THIS_MAIN_ACTIVITY); // 计费包入口Activity路径 if (path.Contains("MANIFEST")) path = path.Replace("MANIFEST", MANIFEST); path = path.Trim(); if (path.StartsWith("activity:") || path.StartsWith("service:") || path.StartsWith("meta-data:") || path.StartsWith("receiver:")) path = "application/" + path; return path.Trim(); } /// <summary> /// 执行多条操作 /// </summary> public void runCMD(List<string> cmds) { if(cmds != null && cmds.Count > 0) runCMD(cmds.ToArray()); } /// <summary> /// 执行多条操作 /// </summary> public void runCMD(string[] cmds) { foreach (string cmd in cmds) { try { runCMD(cmd); } catch (Exception ex) { //if (call != null && !cmd.Equals("")) call("【E】" + "Manifest.runCMD()报错:" + cmd + "\r\n" + ex.Message); } } } /// <summary> /// 自定Manifest处理逻辑 /// path (形如 manifest/application/activity:com.shjc.jsbc.Main),也可定义path为创建新的节点,NEWNODE=<action android:name="android.intent.action.MAIN"/> /// add path1 to path2      (添加path1对应的节点信息到path2) /// replace path1 by path2  () /// remove path             (删除path处的节点) /// get path set attr       (获取指定的节点,并修改其属性值attr) /// GAME_MAIN_ACTIVITY      (指代游戏入口Activity Path) /// THIS_MAIN_ACTIVITY      (指代当前配置计费包apk的Activity Path) /// </summary> public void runCMD(string cmd) { //if (call != null && !cmd.Equals("")) call("【I2】" + cmd); if (cmd.Contains("THIS_MAIN_ACTIVITY") && THIS_MAIN_ACTIVITY.Equals("")) return; if (THIS_MAIN_ACTIVITY.Equals("") && cmd.Equals("remove GAME_MAIN_ACTIVITY/intent-filter")) return; // 当渠道入口为空时,不移除游戏入口中的intent-filter // 移除指定的节点 if(cmd.StartsWith("remove ")) { string path = FullPath(cmd.Substring("remove ".Length)); manifest.Remove(path); } else if(cmd.StartsWith("get ")) { cmd = cmd.Substring("get ".Length).Trim(); string[] A = split(cmd, " set "); if (A.Length > 1) manifest.SetAttribute(FullPath(A[0]), A[1]); } else if (cmd.StartsWith("add ")) { cmd = cmd.Substring("add ".Length).Trim(); string[] A = split(cmd, " to "); if (A.Length > 1) manifest.Add(FullPath(A[0]), FullPath(A[1])); } else if (cmd.StartsWith("replace ")) { cmd = cmd.Substring("replace ".Length).Trim(); string[] A = split(cmd, " by "); if(A.Length > 1) manifest.Replace(FullPath(A[0]), FullPath(A[1])); } } /// <summary> /// 将data按seprator分割为两个子串 /// </summary> public static string[] split(string data, string seprator) { if (data.Contains(seprator)) { int S = data.IndexOf(seprator), E = S + seprator.Length; string[] A = new string[2]; A[0] = data.Substring(0, S).Trim(); A[1] = data.Substring(E).Trim(); return A; } else return new string[] { data }; } } public class FileProcess { #region 文件读取与保存 /// <summary> /// 获取文件中的数据串 /// </summary> public static string fileToString(String filePath) { string str = ""; //获取文件内容 if (System.IO.File.Exists(filePath)) { bool defaultEncoding = filePath.EndsWith(".txt"); System.IO.StreamReader file1; file1 = new System.IO.StreamReader(filePath); //读取文件中的数据 //if (defaultEncoding) file1 = new System.IO.StreamReader(filePath, Encoding.Default);//读取文件中的数据 //else file1 = new System.IO.StreamReader(filePath);                  //读取文件中的数据 str = file1.ReadToEnd(); //读取文件中的全部数据 file1.Close(); file1.Dispose(); } return str; } /// <summary> /// 保存数据data到文件处理过程,返回值为保存的文件名 /// </summary> public static String SaveProcess(String data, String filePath, Encoding encoding = null) { //不存在该文件时先创建 System.IO.StreamWriter file1 = null; if (encoding == null) file1 = new System.IO.StreamWriter(filePath, false/*, System.Text.Encoding.UTF8*/); //文件已覆盖方式添加内容 else file1 = new System.IO.StreamWriter(filePath, false, Encoding.Default); // 使用指定的格式进行保存 file1.Write(data); //保存数据到文件 file1.Close(); //关闭文件 file1.Dispose(); //释放对象 return filePath; } /// <summary> /// 获取当前运行目录 /// </summary> public static string CurDir() { return AppDomain.CurrentDomain.BaseDirectory; } #endregion } } 调用方法:

    Manifest manifesetFile = new Manifest(XmlFilePath); manifesetFile.save();

     

     

    最新回复(0)