private static void propertyWalk(IElement root, JSONObject properties, JSONArray children) { string[] className=getClassNames(root); if(className.Length>0){ IList<string> types=new List<string>(); bool hasProperties=false; foreach(var cls in className){ if(cls.StartsWith("p-",StringComparison.Ordinal) && properties!=null){ hasProperties=true; } else if(cls.StartsWith("u-",StringComparison.Ordinal) && properties!=null){ hasProperties=true; } else if(cls.StartsWith("dt-",StringComparison.Ordinal) && properties!=null){ hasProperties=true; } else if(cls.StartsWith("e-",StringComparison.Ordinal) && properties!=null){ hasProperties=true; } else if(cls.StartsWith("h-",StringComparison.Ordinal)){ types.Add(cls); } } if(types.Count==0 && hasProperties){ // has properties and isn't a microformat // root foreach(var cls in className){ if(cls.StartsWith("p-",StringComparison.Ordinal)){ string value=getPValue(root); if(!StringUtility.isNullOrSpaces(value)) { accumulateValue(properties,cls.Substring(2),value); } } else if(cls.StartsWith("u-",StringComparison.Ordinal)){ accumulateValue(properties,cls.Substring(2), getUValue(root)); } else if(cls.StartsWith("dt-",StringComparison.Ordinal)){ accumulateValue(properties,cls.Substring(3), getDTValue(root,getLastKnownTime(properties))); } else if(cls.StartsWith("e-",StringComparison.Ordinal)){ accumulateValue(properties,cls.Substring(2), getEValue(root)); } } } else if(types.Count>0){ // this is a child microformat // with no properties JSONObject obj=new JSONObject(); obj.put("type", new JSONArray(types)); // for holding child elements with // properties JSONObject subProperties=new JSONObject(); // for holding child microformats with no // property class JSONArray subChildren=new JSONArray(); foreach(var child in root.getChildNodes()){ if(child is IElement) { propertyWalk((IElement)child, subProperties,subChildren); } } if(subChildren.Length>0){ obj.put("children", subChildren); } if(types.Count>0){ // we imply missing properties here // Imply p-name and p-url if(!implyForLink(root,subProperties)){ if(hasSingleChildElementNamed(root,"a")){ implyForLink(getFirstChildElement(root),subProperties); } else { string pvalue=getPValue(root); if(!StringUtility.isNullOrSpaces(pvalue)) { setValueIfAbsent(subProperties,"name", pvalue); } } } // Also imply u-photo if(StringUtility.toLowerCaseAscii(root.getLocalName()).Equals("img") && root.getAttribute("src")!=null){ setValueIfAbsent(subProperties,"photo", getUValue(root)); } if(!subProperties.has("photo")){ IList<IElement> images=root.getElementsByTagName("img"); // If there is only one descendant image, imply // u-photo if(images.Count==1){ setValueIfAbsent(subProperties,"photo", getUValue(images[0])); } } } obj.put("properties", subProperties); if(hasProperties){ foreach(var cls in className){ if(cls.StartsWith("p-",StringComparison.Ordinal)){ // property JSONObject clone=copyJson(obj); clone.put("value",getPValue(root)); accumulateValue(properties,cls.Substring(2),clone); } else if(cls.StartsWith("u-",StringComparison.Ordinal)){ // URL JSONObject clone=copyJson(obj); clone.put("value",getUValue(root)); accumulateValue(properties,cls.Substring(2),clone); } else if(cls.StartsWith("dt-",StringComparison.Ordinal)){ // date/time JSONObject clone=copyJson(obj); clone.put("value",getDTValue(root,getLastKnownTime(properties))); accumulateValue(properties,cls.Substring(3),clone); } else if(cls.StartsWith("e-",StringComparison.Ordinal)){ // date/time JSONObject clone=copyJson(obj); clone.put("value",getEValue(root)); accumulateValue(properties,cls.Substring(2),clone); } } } else { children.put(obj); } return; } } foreach(var child in root.getChildNodes()){ if(child is IElement) { propertyWalk((IElement)child,properties,children); } } }
private static void accumulateValue(JSONObject obj, string key, Object value) { JSONArray arr=null; if(obj.has(key)){ arr=obj.getJSONArray(key); } else { arr=new JSONArray(); obj.put(key, arr); } arr.put(value); }
/** * * Scans an HTML element for Microformats.org metadata. * The resulting _object will contain an "items" property, * an array of all Microformats items. Each item will * have a "type" and "properties" properties. * * @param root the element to scan. * @return a JSON _object containing Microformats metadata */ public static JSONObject getMicroformatsJSON(IElement root) { if((root)==null)throw new ArgumentNullException("root"); JSONObject obj=new JSONObject(); JSONArray items=new JSONArray(); propertyWalk(root,null,items); obj.put("items", items); return obj; }
public static JSONObject getRelJSON(IElement root) { if((root)==null)throw new ArgumentNullException("root"); JSONObject obj=new JSONObject(); JSONArray items=new JSONArray(); JSONObject item=new JSONObject(); accumulateValue(item,"type","rel"); JSONObject props=new JSONObject(); relWalk(root,props); item.put("properties", props); items.put(item); obj.put("items", items); return obj; }
private static void setValueIfAbsent(JSONObject obj, string key, Object value) { if(!obj.has(key)){ JSONArray arr=null; arr=new JSONArray(); obj.put(key, arr); arr.put(value); } }
public static Object patch(Object o, JSONArray patch) { // clone the _object in case of failure o=cloneJsonObject(o); for(int i=0;i<patch.Length;i++){ Object op=patch[i]; if(!(op is JSONObject)) throw new ArgumentException("patch"); if(o==null) throw new InvalidOperationException("patch"); JSONObject patchOp=(JSONObject)op; // NOTE: This algorithm requires "op" to exist // only once; the JSONObject, however, does not // allow duplicates string opStr=getString(patchOp,"op"); if(opStr==null) throw new ArgumentException("patch"); if("add".Equals(opStr)){ // operation Object value=null; try { value=patchOp["value"]; } catch(System.Collections.Generic.KeyNotFoundException){ throw new ArgumentException("patch "+opStr+" value"); } o=addOperation(o,opStr,getString(patchOp,"path"),value); } else if("replace".Equals(opStr)){ // operation Object value=null; try { value=patchOp["value"]; } catch(System.Collections.Generic.KeyNotFoundException){ throw new ArgumentException("patch "+opStr+" value"); } o=replaceOperation(o,opStr,getString(patchOp,"path"),value); } else if("remove".Equals(opStr)){ // Remove operation string path=patchOp.getString("path"); if(path==null)throw new ArgumentException("patch "+opStr+" path"); if(path.Length==0) { o=null; } else { removeOperation(o,opStr,getString(patchOp,"path")); } } else if("move".Equals(opStr)){ string path=patchOp.getString("path"); if(path==null)throw new ArgumentException("patch "+opStr+" path"); string fromPath=patchOp.getString("from"); if(fromPath==null)throw new ArgumentException("patch "+opStr+" from"); if(path.StartsWith(fromPath,StringComparison.Ordinal)) throw new ArgumentException("patch "+opStr); Object movedObj=removeOperation(o,opStr,fromPath); o=addOperation(o,opStr,path,cloneJsonObject(movedObj)); } else if("copy".Equals(opStr)){ string path=patchOp.getString("path"); if(path==null)throw new ArgumentException("patch "+opStr+" path"); string fromPath=patchOp.getString("from"); if(fromPath==null)throw new ArgumentException("patch "+opStr+" from"); JSONPointer pointer=JSONPointer.fromPointer(o, path); if(!pointer.exists()) throw new System.Collections.Generic.KeyNotFoundException("patch "+opStr+" "+fromPath); Object copiedObj=pointer.getValue(); o=addOperation(o,opStr,path,cloneJsonObject(copiedObj)); } else if("test".Equals(opStr)){ string path=patchOp.getString("path"); if(path==null)throw new ArgumentException("patch "+opStr+" path"); Object value=null; try { value=patchOp["value"]; } catch(System.Collections.Generic.KeyNotFoundException){ throw new ArgumentException("patch "+opStr+" value"); } JSONPointer pointer=JSONPointer.fromPointer(o, path); if(!pointer.exists()) throw new System.Collections.Generic.KeyNotFoundException("patch "+opStr+" "+path); Object testedObj=pointer.getValue(); if((testedObj==null) ? (value!=null) : !testedObj.Equals(value)) throw new InvalidOperationException("patch "+opStr); } } return (o==null) ? JSONObject.NULL : o; }
public void writeObjectToStream(CacheControl o, Stream stream) { JSONObject jsonobj=new JSONObject(); jsonobj.put("cacheability",o.cacheability); jsonobj.put("noStore",o.noStore); jsonobj.put("noTransform",o.noTransform); jsonobj.put("mustRevalidate",o.mustRevalidate); jsonobj.put("requestTime",Convert.ToString(o.requestTime,CultureInfo.InvariantCulture)); jsonobj.put("responseTime",Convert.ToString(o.responseTime,CultureInfo.InvariantCulture)); jsonobj.put("maxAge",Convert.ToString(o.maxAge,CultureInfo.InvariantCulture)); jsonobj.put("date",Convert.ToString(o.date,CultureInfo.InvariantCulture)); jsonobj.put("uri",o.uri); jsonobj.put("requestMethod",o.requestMethod); jsonobj.put("code",o.code); jsonobj.put("age",Convert.ToString(o.age,CultureInfo.InvariantCulture)); JSONArray jsonarr=new JSONArray(); foreach(var header in o.headers){ jsonarr.put(header); } jsonobj.put("headers",jsonarr); StreamUtility.stringToStream(jsonobj.ToString(),stream); }
/** * Produce a JSONObject by combining a JSONArray of names with the values * of this JSONArray. * @param names A JSONArray containing a list of key strings. These will be * paired with the values. * @return A JSONObject, or null if there are no names or if this JSONArray * has no values. */ public JSONObject toJSONObject(JSONArray names) { if (names == null || names.Length == 0 || length() == 0) return null; JSONObject jo = new JSONObject(); for (int i = 0; i < names.Length; i += 1) { jo.put(names.getString(i), opt(i)); } return jo; }
/** * Produce a JSONArray containing the values of the members of this * JSONObject. * @param names A JSONArray containing a list of key strings. This * determines the sequence of the values in the result. * @return A JSONArray of values. */ public JSONArray toJSONArray(JSONArray names) { if (names == null || names.Length == 0) return null; JSONArray ja = new JSONArray(); for (int i = 0; i < names.Length; i += 1) { ja.put(opt(names.getString(i))); } return ja; }
/** * Produce a JSONArray containing the names of the elements of this * JSONObject. * @return A JSONArray containing the key strings, or null if the JSONObject * is empty. */ public JSONArray names() { JSONArray ja = new JSONArray(); foreach(var key in keys()) { ja.put(key); } if (ja.Length == 0) return null; return ja; }
/** * Accumulate values under a key. It is similar to the put method except * that if there is already an _object stored under the key then a * JSONArray is stored under the key to hold all of the accumulated values. * If there is already a JSONArray, then the new value is appended to it. * In contrast, the put method replaces the previous value. * * @param key A key _string. * @param value An _object to be accumulated under the key. * @return this. * @ if the key is null */ public JSONObject accumulate(string key, Object value) { JSONArray a; Object o = opt(key); if (o == null) { put(key, value); } else if (o is JSONArray) { a = (JSONArray)o; a.put(value); } else { a = new JSONArray(); a.put(o); a.put(value); put(key, a); } return this; }
public static void main(string[] args) { string json="["+ "{ # foo\n\"foo-key\":\"foo-value\"},\n"+ "{ /* This is a\n # multiline comment.*/\n\"bar-key\":\"bar-value\"}]"; Console.WriteLine(json); JSONArray obj=new JSONArray(json, JSONObject.OPTION_SHELL_COMMENTS | // Support SHELL-style comments JSONObject.OPTION_ADD_COMMENTS // Incorporate comments in the JSON _object ); Console.WriteLine(obj); // Output the JSON _object // Objects with comments associated with them will // now contain a "@comment" key; get the JSON Pointers // (RFC6901) to these objects and remove the "@comment" keys. IDictionary<string,Object> pointers=JSONPointer.getPointersWithKeyAndRemove(obj,"@comment"); // For each JSON Pointer, get its corresponding _object. // They will always be JSONObjects. foreach(var pointer in pointers.Keys){ JSONObject subobj=(JSONObject)JSONPointer.getObject(obj,pointer); Console.WriteLine(subobj); // Output the _object Console.WriteLine(pointers[pointer]); // Output the key's value } }