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); } } }