/** * * 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; }
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 int[] getLastKnownTime(JSONObject obj) { if(obj.has("start")){ JSONArray arr=obj.getJSONArray("start"); //Console.WriteLine("start %s",arr); Object result=arr[arr.Length-1]; if(result is string){ int[] components=new int[]{ Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue }; if(matchDateTimePattern((string)result, new string[]{"%Y-%M-%d","%Y-%D"}, new string[]{"%H:%m:%s","%H:%m", "%H:%m:%s%Z:%z", "%H:%m:%s%Z%z","%H:%m:%s%G", "%H:%m%Z:%z","%H:%m%Z%z","%H:%m%G"}, components,true,true,true)){ // reset the time components components[3]=Int32.MinValue; components[4]=Int32.MinValue; components[5]=Int32.MinValue; components[6]=Int32.MinValue; components[7]=Int32.MinValue; //Console.WriteLine("match %s",Arrays.ToString(components)); return components; } else { //Console.WriteLine("no match"); } } } return null; }
private static bool implyForLink(IElement root, JSONObject subProperties) { if(StringUtility.toLowerCaseAscii(root.getLocalName()).Equals("a") && root.getAttribute("href")!=null){ // get the link's URL setValueIfAbsent(subProperties,"url", getUValue(root)); IList<IElement> elements=getChildElements(root); if(elements.Count==1 && StringUtility.toLowerCaseAscii(elements[0].getLocalName()).Equals("img")){ string pValue=getPValue(elements[0]); // try to get the ALT/TITLE from the image if(StringUtility.isNullOrSpaces(pValue)) { pValue=getPValue(root); // if empty, get text from link instead } setValueIfAbsent(subProperties,"name", pValue); // get the SRC of the image setValueIfAbsent(subProperties,"photo", getUValue(elements[0])); } else { // get the text content string pvalue=getPValue(root); if(!StringUtility.isNullOrSpaces(pvalue)) { setValueIfAbsent(subProperties,"name", pvalue); } } return true; } return false; }
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); }
private static JSONObject copyJson(JSONObject obj) { try { return new JSONObject(obj.ToString()); } catch(Json.InvalidJsonException){ return null; } }
private static void relWalk(IElement root, JSONObject properties) { string[] className=getRelNames(root); if(className.Length>0){ string href=getHref(root); if(!StringUtility.isNullOrSpaces(href)){ foreach(var cls in className){ accumulateValue(properties,cls,href); } } } foreach(var child in root.getChildNodes()){ if(child is IElement) { relWalk((IElement)child,properties); } } }
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 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; }
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); }
public CacheControl readObjectFromStream(PeterO.Support.InputStream stream) { try { JSONObject jsonobj=new JSONObject(StreamUtility.streamToString(stream)); CacheControl cc=new CacheControl(); cc.cacheability=jsonobj.getInt("cacheability"); cc.noStore=jsonobj.getBoolean("noStore"); cc.noTransform=jsonobj.getBoolean("noTransform"); cc.mustRevalidate=jsonobj.getBoolean("mustRevalidate"); cc.requestTime=Int64.Parse(jsonobj.getString("requestTime"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.responseTime=Int64.Parse(jsonobj.getString("responseTime"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.maxAge=Int64.Parse(jsonobj.getString("maxAge"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.date=Int64.Parse(jsonobj.getString("date"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.code=jsonobj.getInt("code"); cc.age=Int64.Parse(jsonobj.getString("age"),NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); cc.uri=jsonobj.getString("uri"); cc.requestMethod=jsonobj.getString("requestMethod"); if(cc.requestMethod!=null) { cc.requestMethod=StringUtility.toLowerCaseAscii(cc.requestMethod); } cc.headers=new List<string>(); JSONArray jsonarr=jsonobj.getJSONArray("headers"); for(int i=0;i<jsonarr.Length;i++){ string str=jsonarr.getString(i); if(str!=null && (i%2)!=0){ str=StringUtility.toLowerCaseAscii(str); if("age".Equals(str) || "connection".Equals(str) || "keep-alive".Equals(str) || "proxy-authenticate".Equals(str) || "proxy-authorization".Equals(str) || "te".Equals(str) || "trailers".Equals(str) || "transfer-encoding".Equals(str) || "upgrade".Equals(str)){ // Skip "age" header field and // hop-by-hop header fields i++; continue; } } cc.headers.Add(str); } return cc; } catch(InvalidCastException e){ Console.WriteLine(e.StackTrace); return null; } catch(FormatException e){ Console.WriteLine(e.StackTrace); return null; } catch (Json.InvalidJsonException e) { Console.WriteLine(e.StackTrace); return null; } }
private static string getString(JSONObject o, string key) { try { return o.getString(key); } catch(System.Collections.Generic.KeyNotFoundException){ return null; } }
/** * 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; }