/// <summary> /// Converts an XML document to an IJavaScriptObject (JSON). /// <see cref="http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html?page=1">Stefan Goessner</see> /// <see cref="http://developer.yahoo.com/common/json.html#xml">Yahoo XML JSON</see> /// </summary> /// <param name="n">The XmlNode to serialize to JSON.</param> /// <returns>A IJavaScriptObject.</returns> public static IJavaScriptObject GetIJavaScriptObjectFromXmlNode(XmlNode n) { if (n == null) return null; //if (xpath == "" || xpath == "/") // xpath = n.Name; System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"\w+|\W+", System.Text.RegularExpressions.RegexOptions.Compiled); JavaScriptObject o = new JavaScriptObject(); if (n.NodeType == XmlNodeType.Element) { for (int i = 0; i < n.Attributes.Count; i++) { o.Add("@" + n.Attributes[i].Name, n.Attributes[i].Value); } if (n.FirstChild != null) // element has child nodes { int textChild = 0; bool hasElementChild = false; for (XmlNode e = n.FirstChild; e != null; e = e.NextSibling) { if (e.NodeType == XmlNodeType.Element) hasElementChild = true; if (e.NodeType == XmlNodeType.Text && r.IsMatch(e.InnerText)) textChild++; // non-whitespace text } if (hasElementChild) { if (textChild < 2) // structured element with evtl. a single text node { for (XmlNode e = n.FirstChild; e != null; e = e.NextSibling) { if (e.NodeType == XmlNodeType.Text) { o.Add("#text", e.InnerText); } else if (o.ContainsKey(e.Name)) { if (o[e.Name] is JavaScriptArray) { ((JavaScriptArray)o[e.Name]).Add(GetIJavaScriptObjectFromXmlNode(e)); } else { IJavaScriptObject _o = o[e.Name]; JavaScriptArray a = new JavaScriptArray(); a.Add(_o); a.Add(GetIJavaScriptObjectFromXmlNode(e)); o[e.Name] = a; } } else { o.AddInternal(e.Name, GetIJavaScriptObjectFromXmlNode(e)); } } } } else if (textChild > 0) { if (n.Attributes.Count == 0) return new JavaScriptString(n.InnerText); else o.Add("#text", n.InnerText); } } if (n.Attributes.Count == 0 && n.FirstChild == null) return new JavaScriptString(n.InnerText); } else if (n.NodeType == XmlNodeType.Document) return GetIJavaScriptObjectFromXmlNode(((XmlDocument)n).DocumentElement); else throw new NotSupportedException("Unhandled node type '" + n.NodeType + "'."); return o; }
/// <summary> /// Deserialzes from ajax XML. /// </summary> /// <param name="n">The n.</param> /// <returns></returns> internal static IJavaScriptObject DeserialzeFromAjaxXml(XmlNode n) { switch (n.Name) { case "array": JavaScriptArray a = new JavaScriptArray(); foreach (XmlNode item in n.ChildNodes) a.Add(DeserialzeFromAjaxXml(item)); return a; case "boolean": JavaScriptBoolean b = new JavaScriptBoolean(n.InnerText == "true"); return b; case "number": JavaScriptNumber i = new JavaScriptNumber(); i.Append(n.InnerText); return i; case "string": JavaScriptString s = new JavaScriptString(); s.Append(n.InnerText); return s; case "object": JavaScriptObject o = new JavaScriptObject(); foreach (XmlNode p in n.SelectNodes("property")) { if (p.Attributes["name"] == null || p.ChildNodes.Count != 1) continue; o.AddInternal(p.Attributes["name"].Value, DeserialzeFromAjaxXml(p.ChildNodes[0])); } return o; } return null; }
private static IJavaScriptObject Process(IJavaScriptObject root, string key, string value) { string[] parts = key.Split(new char[] { '.', '[', ']' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 1) { root = new JavaScriptString(value); } else { if (IsNumber(parts[1]) && !(root is JavaScriptArray)) { root = new JavaScriptArray(); } if (!IsNumber(parts[1]) && !(root is JavaScriptObject)) { root = new JavaScriptObject(); } IJavaScriptObject prev = root; for (int i = 1; i < parts.Length; i++) { string part = parts[i]; if (IsNumber(part)) { int index = Convert.ToInt32(part); if (i < parts.Length - 1) { if (((JavaScriptArray)prev).Count > index) { bool nextArray = IsNumber(parts[i + 1]); if ((nextArray && ((JavaScriptArray)prev)[index] is JavaScriptArray) || (!nextArray && ((JavaScriptArray)prev)[index] is JavaScriptObject)) { prev = ((JavaScriptArray)prev)[index]; continue; } ((JavaScriptArray)prev)[index] = Process(parts, i, value); break; } } else { //最后一段应该是string if (((JavaScriptArray)prev).Count > index) { ((JavaScriptArray)prev)[index] = Process(parts, i, value); break; } } for (int j = ((JavaScriptArray)prev).Count; j < index; j++) { ((JavaScriptArray)prev).Add(null); } ((JavaScriptArray)prev).Add(Process(parts, i, value)); prev = ((JavaScriptArray)prev)[index]; break; } else { if (((JavaScriptObject)prev).ContainsKey(part)) { if (i < parts.Length - 1) { bool nextArray = IsNumber(parts[i + 1]); if ((nextArray && ((JavaScriptObject)prev)[part] is JavaScriptArray) || (!nextArray && ((JavaScriptObject)prev)[part] is JavaScriptObject)) { prev = ((JavaScriptObject)prev)[part]; continue; } } ((JavaScriptObject)prev)[part] = Process(parts, i, value); break; } else { ((JavaScriptObject)prev).AddInternal(part, Process(parts, i, value)); break; } } } } return(root); }
/// <summary> /// Read an array object from the JSON string. /// </summary> /// <returns>Returns an ArrayList with all objects.</returns> internal JavaScriptArray ReadArray() { JavaScriptArray a = new JavaScriptArray(); if (_ch == JSON_ARRAY_BEGIN) { ReadNext(); ReadWhiteSpaces(); if (_ch == JSON_ARRAY_END) { ReadNext(); return a; } while (_ch != END_OF_STRING) { a.Add(GetObject()); ReadWhiteSpaces(); if (_ch == JSON_ARRAY_END) { ReadNext(); return a; } else if (_ch != JSON_ITEMS_SEPARATOR) { break; } ReadNext(); ReadWhiteSpaces(); } } else { throw new NotSupportedException("Array could not be read."); } return a; }
/// <summary> /// Converts an XML document to an IJavaScriptObject (JSON). /// <see cref="http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html?page=1">Stefan Goessner</see> /// <see cref="http://developer.yahoo.com/common/json.html#xml">Yahoo XML JSON</see> /// </summary> /// <param name="n">The XmlNode to serialize to JSON.</param> /// <returns>A IJavaScriptObject.</returns> public static IJavaScriptObject GetIJavaScriptObjectFromXmlNode(XmlNode n) { if (n == null) { return(null); } //if (xpath == "" || xpath == "/") // xpath = n.Name; System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"\w+|\W+", System.Text.RegularExpressions.RegexOptions.Compiled); JavaScriptObject o = new JavaScriptObject(); if (n.NodeType == XmlNodeType.Element) { for (int i = 0; i < n.Attributes.Count; i++) { o.Add("@" + n.Attributes[i].Name, n.Attributes[i].Value); } if (n.FirstChild != null) // element has child nodes { int textChild = 0; bool hasElementChild = false; for (XmlNode e = n.FirstChild; e != null; e = e.NextSibling) { if (e.NodeType == XmlNodeType.Element) { hasElementChild = true; } if (e.NodeType == XmlNodeType.Text && r.IsMatch(e.InnerText)) { textChild++; // non-whitespace text } } if (hasElementChild) { if (textChild < 2) // structured element with evtl. a single text node { for (XmlNode e = n.FirstChild; e != null; e = e.NextSibling) { if (e.NodeType == XmlNodeType.Text) { o.Add("#text", e.InnerText); } else if (o.ContainsKey(e.Name)) { if (o[e.Name] is JavaScriptArray) { ((JavaScriptArray)o[e.Name]).Add(GetIJavaScriptObjectFromXmlNode(e)); } else { IJavaScriptObject _o = o[e.Name]; JavaScriptArray a = new JavaScriptArray(); a.Add(_o); a.Add(GetIJavaScriptObjectFromXmlNode(e)); o[e.Name] = a; } } else { o.AddInternal(e.Name, GetIJavaScriptObjectFromXmlNode(e)); } } } } else if (textChild > 0) { if (n.Attributes.Count == 0) { return(new JavaScriptString(n.InnerText)); } else { o.Add("#text", n.InnerText); } } } if (n.Attributes.Count == 0 && n.FirstChild == null) { return(new JavaScriptString(n.InnerText)); } } else if (n.NodeType == XmlNodeType.Document) { return(GetIJavaScriptObjectFromXmlNode(((XmlDocument)n).DocumentElement)); } else { throw new NotSupportedException("Unhandled node type '" + n.NodeType + "'."); } return(o); }
/// <summary> /// Converts an IJavaScriptObject into an NET object. /// </summary> /// <param name="o">The IJavaScriptObject object to convert.</param> /// <param name="t"></param> /// <returns>Returns a .NET object.</returns> public override object Deserialize(IJavaScriptObject o, Type t) { JavaScriptObject ht = o as JavaScriptObject; if (ht == null) { throw new NotSupportedException(); } if (!ht.ContainsKey("columns") || !(ht["columns"] is JavaScriptArray) || !ht.ContainsKey("columnTypes") || !(ht["columnTypes"] is JavaScriptArray) || !ht.ContainsKey("rows") || !(ht["rows"] is JavaScriptArray)) { throw new NotSupportedException(); } JavaScriptArray columns = (JavaScriptArray)ht["columns"]; JavaScriptArray columnTypes = (JavaScriptArray)ht["columnTypes"]; JavaScriptArray rows = (JavaScriptArray)ht["rows"]; if (columns.Count != columnTypes.Count) { throw new NotSupportedException(); } DataTable dt = new DataTable(); DataRow row = null; Type colType; JavaScriptString columnName; JavaScriptString columnType; if (ht.ContainsKey("name") && ht["name"] is JavaScriptString) { dt.TableName = ht["name"].ToString(); } for (int i = 0; i < columns.Count; i++) { columnName = (JavaScriptString)columns[i]; columnType = (JavaScriptString)columnTypes[i]; colType = Type.GetType(columnType, true); dt.Columns.Add(columnName, colType); } JavaScriptArray cols = null; object obj; for (int y = 0; y < rows.Count; y++) { // if(!(r is JavaScriptArray)) // continue; cols = (JavaScriptArray)rows[y]; row = dt.NewRow(); for (int i = 0; i < cols.Count; i++) { //row[i] = JavaScriptDeserializer.Deserialize((IJavaScriptObject)cols[i], dt.Columns[i].DataType); obj = JavaScriptDeserializer.Deserialize((IJavaScriptObject)cols[i], dt.Columns[i].DataType); row[i] = (obj == null) ? DBNull.Value : obj; } dt.Rows.Add(row); } return(dt); }