private void CloneStep(KeyValueEx kve, KeyValueEx des) { if (kve == null || des == null) { return; } foreach (var item in kve) { if (item.Value is KeyValueEx) { des[item.Key] = new KeyValueEx(); CloneStep(item.Value as KeyValueEx, des[item.Key] as KeyValueEx); } else if (item.Value is KeyValueExList) { KeyValueExList vle = item.Value as KeyValueExList; KeyValueExList vle1 = new KeyValueExList(); des[item.Key] = vle1; foreach (var item1 in vle) { KeyValueEx des1 = new KeyValueEx(); CloneStep(item1, des1); vle1.Add(des1); } } else if (item.Value is StringExList) { StringExList vl = item.Value as StringExList; StringExList vl1 = new StringExList(); des[item.Key] = vl1; foreach (var item2 in vl) { vl1.Add(item2); } } else { des[item.Key] = item.Value.ToString(); } } }
/// <summary> /// 转换字符串到list数组,格式["123","234","345"] /// </summary> /// <param name="s">字符串,包括中括号</param> /// <param name="vl">存放元素的list</param> /// <param name="now_index">当前字符串处理到的索引</param> public static void StringToStringExList(string s, StringExList vl, ref int now_index) { if (now_index >= s.Length) { return; } Stack <char> sc = new Stack <char>(); string value = null; int i = now_index; for ( ; i < s.Length; i++) { // 如果栈未空,一直忽略到左中括号为止 if (sc.Count == 0 && s[i] != '[') { continue; } else if (sc.Count == 0 && s[i] == '[') { sc.Push(s[i]); continue; } else { if (sc.Peek() == '[') { // 暂只支持字符串的元素,说明元素开始了 if (s[i] == '"') { sc.Push(s[i]); continue; } if (s[i] == ',') { sc.Push(s[i]); continue; } // 数组转换结束 if (s[i] == ']') { break; } } else if (sc.Peek() == '"') { // 转义字符开始 if (s[i] == '\\') { sc.Push(s[i]); continue; } // 元素的字符串结束了 if (s[i] == '"') { vl.Add(new StringEx(value)); sc.Pop(); continue; } value += s[i]; } else if (sc.Peek() == ',') { // 逗号间隔符遇到引号,说明下一个元素开始了 if (s[i] == '"') { sc.Pop(); sc.Push(s[i]); value = null; continue; } } else if (sc.Peek() == '\\') { sc.Pop(); value += s[i]; } else { } } } now_index = i; }
/// <summary> /// 转换当前节点为字典或list /// Item节点还是字典不变,但是Item节点作为value所对应的key是不存在的 /// 它对应的key作为上一级List的成员保存了起来 /// 例: /// 原来,大括号表示字典类型 /// List:{Item:{id:1},Item:{id:1}} /// 现在,中括号实际上是ListEx类型 /// List(Item):[{id:1},{id:1}] /// </summary> /// <param name="xn"></param> /// <param name="dso"></param> private static void XmlNodeToKeyValueEx(XmlNode xn, object dso, string list_name) { if (xn == null) { return; } XmlNodeList xnl = xn.ChildNodes; KeyValueExList kv_list = null; KeyValueEx kv = null; StringExList sel = null; if (dso is KeyValueEx) { kv = dso as KeyValueEx; } if (dso is KeyValueExList) { kv_list = dso as KeyValueExList; } if (dso is StringExList) { sel = dso as StringExList; } IAttr iattr = null; object temp = null; // 如果没有子节点了,退出递归的条件 // 后一个条件是为了忽略xml的强制数据条件<![CDATA[...]]>,不把它当作子节点处理 if (xnl.Count == 0 || xn.InnerText == xn.InnerXml || (xnl.Count == 1 && (xnl[0].NodeType == XmlNodeType.Text || xnl[0].NodeType == XmlNodeType.CDATA))) { XmlElement xe = xn as XmlElement; StringEx se = null; if (string.IsNullOrEmpty(xe.InnerText)) { if (xn.FirstChild == null && xe != null && xe.IsEmpty) { se = new StringEx(null); } else { se = new StringEx(""); } } else { se = new StringEx(xe.InnerText); } //如果本节点是字典类型 if (kv != null) { // 添加键值对 kv.Add(xn.Name, se); } //// 如果本节点是list类型,直接添加值,忽略键,在这个版本下不可能出现的键值列表又是stringex //else if( kv_list != null ) //{ // kv_list.Add( se ); //} else if (sel != null) { sel.Add(se); } else { throw new Exception("转换失败"); } iattr = se as IAttr; if (iattr != null && xn.Attributes != null) { foreach (XmlAttribute item in xn.Attributes) { iattr.Attr[item.Name] = item.Value; } } return; } else { // 保存子节点(item)的 string son_name = null; // 如果节点名在强制节点名中,那么把这个节点强制看作List,以当前节点的第一个子节点作为子节点名 // 防止把一个list一个item当作字典处理的这种情况 // 或者如果有重复的子节点 if (IsXmlNodeList(xn, list_name, ref son_name) || HasXmlNodeDuplicateChild(xn, ref son_name)) { //提前处理了字符数组的情况 if (xn.FirstChild.FirstChild == null || xn.FirstChild.InnerText == xn.FirstChild.InnerXml || (xn.FirstChild.NodeType == XmlNodeType.Text || xn.FirstChild.NodeType == XmlNodeType.CDATA)) { temp = new StringExList() { SonName = son_name }; } else { // 装子节点的对象为list // 实际保存为DictionaryEx<"List", List<object>> temp = new KeyValueExList(son_name); } } else { temp = new KeyValueEx(); } if (kv != null) { // 以空字典添加节点 kv.Add(xn.Name, temp); } else if (kv_list != null) { kv_list.Add((KeyValueEx)temp); } else { throw new Exception("转换失败"); } } iattr = temp as IAttr; if (iattr != null) { foreach (XmlAttribute item in xn.Attributes) { iattr.Attr[item.Name] = item.Value; } } // 子节点递归 for (int i = 0; i < xnl.Count; i++) { XmlNodeToKeyValueEx(xnl[i], temp, list_name); } }