public AppendGraphMLAttributeValue ( |
||
edgeOrVertexXmlNode | ||
attributeID | String | |
attributeValue | Double | |
return | void |
AddStatusUpdates ( ref GraphMLXmlDocument oGraphMLXmlDocument, ref XmlNode oVertexXmlNode, string userID, Dictionary<string, List<Dictionary<string, object>>> statusUpdates ) { List<Dictionary<string, object>>.Enumerator en; string currentStatusUpdate = ""; string currentStatusTags = ""; //Add status updates if (statusUpdates.ContainsKey(userID)) { en = statusUpdates[userID].GetEnumerator(); currentStatusUpdate = ""; currentStatusTags = ""; while (en.MoveNext() && currentStatusUpdate.Length < 8000) { if (((JSONObject)en.Current["message"]).String.Equals("")) continue; currentStatusUpdate += ((JSONObject)en.Current["message"]).String + "\n\n"; //Add tags if (en.Current["message_tags"] is List<JSONObject>) { foreach (JSONObject ob in (List<JSONObject>)en.Current["message_tags"]) { currentStatusTags += ob.String + ","; } currentStatusTags = currentStatusTags.Remove(currentStatusTags.Length - 1); currentStatusTags += "\n\n"; } } oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "statuses", currentStatusUpdate); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "statuses_tags", currentStatusTags); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "statuses_urls", GetURLs(currentStatusUpdate, ' ')); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "statuses_hashtags", GetHashtags(currentStatusUpdate, ' ')); } }
AppendVertexXmlNodes ( String sSearchTerm, WhatToInclude eWhatToInclude, Int32 iMaximumVideos, GraphMLXmlDocument oGraphMLXmlDocument, RequestStatistics oRequestStatistics, out HashSet<String> oVideoIDs, out Dictionary< String, LinkedList<String> > oCategoryDictionary ) { Debug.Assert( !String.IsNullOrEmpty(sSearchTerm) ); Debug.Assert(iMaximumVideos> 0); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oRequestStatistics != null); AssertValid(); ReportProgress("Getting a list of videos."); // This is used to skip duplicate videos in the results returned by // YouTube. (I'm not sure why YouTube sometimes returns duplicates, // but it does.) oVideoIDs = new HashSet<String>(); // If an edge should be included for each pair of videos that share the // same category, the key is a lower-case category and the value is a // LinkedList of the video IDs that have the category. if ( WhatToIncludeFlagIsSet(eWhatToInclude, WhatToInclude.SharedCategoryEdges) ) { oCategoryDictionary = new Dictionary< String, LinkedList<String> >(); } else { oCategoryDictionary = null; } String sUrl = String.Format( "http://gdata.youtube.com/feeds/api/videos?q={0}" , EncodeUrlParameter(sSearchTerm) ); // The document consists of an "entry" XML node for each video. foreach ( XmlNode oEntryXmlNode in EnumerateXmlNodes(sUrl, "a:feed/a:entry", iMaximumVideos, false, oRequestStatistics) ) { XmlNamespaceManager oXmlNamespaceManager = CreateXmlNamespaceManager(oEntryXmlNode.OwnerDocument); // Use the video ID as the GraphML vertex name. The video title // can't be used because it is not unique. String sVideoID; if ( !XmlUtil2.TrySelectSingleNodeAsString(oEntryXmlNode, "media:group/yt:videoid/text()", oXmlNamespaceManager, out sVideoID) || oVideoIDs.Contains(sVideoID) ) { continue; } oVideoIDs.Add(sVideoID); XmlNode oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode( sVideoID); AppendStringGraphMLAttributeValue(oEntryXmlNode, "a:title/text()", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, TitleID); AppendStringGraphMLAttributeValue(oEntryXmlNode, "a:author/a:name/text()", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, AuthorID); AppendDoubleGraphMLAttributeValue(oEntryXmlNode, "gd:rating/@average", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, RatingID); AppendInt32GraphMLAttributeValue(oEntryXmlNode, "yt:statistics/@viewCount", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, ViewsID); AppendInt32GraphMLAttributeValue(oEntryXmlNode, "yt:statistics/@favoriteCount", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, FavoritedID); AppendInt32GraphMLAttributeValue(oEntryXmlNode, "gd:comments/gd:feedLink/@countHint", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, CommentsID); AppendYouTubeDateGraphMLAttributeValue(oEntryXmlNode, "a:published/text()", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, CreatedDateUtcID); AppendStringGraphMLAttributeValue(oEntryXmlNode, "media:group/media:thumbnail/@url", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, NodeXLGraphMLUtil.VertexImageFileID); if ( AppendStringGraphMLAttributeValue(oEntryXmlNode, "media:group/media:player/@url", oXmlNamespaceManager, oGraphMLXmlDocument, oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuActionID) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuTextID, "Play Video in Browser"); } if (oCategoryDictionary != null) { CollectCategories(oEntryXmlNode, sVideoID, oXmlNamespaceManager, oCategoryDictionary); } } }
AppendEdgeXmlNode ( GraphMLXmlDocument graphMLXmlDocument, String vertex1ID, String vertex2ID, String relationship ) { Debug.Assert(graphMLXmlDocument != null); Debug.Assert( !String.IsNullOrEmpty(vertex1ID) ); Debug.Assert( !String.IsNullOrEmpty(vertex2ID) ); Debug.Assert( !String.IsNullOrEmpty(relationship) ); XmlNode edgeXmlNode = graphMLXmlDocument.AppendEdgeXmlNode( vertex1ID, vertex2ID); graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, EdgeRelationshipID, relationship); return (edgeXmlNode); }
AppendStartTimeRelationshipDateUtcGraphMLAttributeValue ( GraphMLXmlDocument oGraphMLXmlDocument, XmlNode oEdgeXmlNode, RequestStatistics oRequestStatistics ) { Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oEdgeXmlNode != null); Debug.Assert(oRequestStatistics != null); AssertValid(); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oEdgeXmlNode, TwitterGraphMLUtil.EdgeRelationshipDateUtcID, DateTimeUtil2.ToCultureInvariantString( oRequestStatistics.StartTimeUtc) ); }
AppendEdgeXmlNode ( GraphMLXmlDocument oGraphMLXmlDocument, String sVertex1ID, String sVertex2ID, String sRelationship ) { Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert( !String.IsNullOrEmpty(sVertex1ID) ); Debug.Assert( !String.IsNullOrEmpty(sVertex2ID) ); Debug.Assert( !String.IsNullOrEmpty(sRelationship) ); AssertValid(); XmlNode oEdgeXmlNode = oGraphMLXmlDocument.AppendEdgeXmlNode( sVertex1ID, sVertex2ID); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oEdgeXmlNode, RelationshipID, sRelationship); return (oEdgeXmlNode); }
AppendSampleThumbnails ( Dictionary<String, XmlNode> oTagDictionary, GraphMLXmlDocument oGraphMLXmlDocument, String sApiKey, RequestStatistics oRequestStatistics ) { Debug.Assert(oTagDictionary != null); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert( !String.IsNullOrEmpty(sApiKey) ); Debug.Assert(oRequestStatistics != null); AssertValid(); foreach (KeyValuePair<String, XmlNode> oKeyValuePair in oTagDictionary) { String sTag = oKeyValuePair.Key; ReportProgress("Getting sample image file for \"" + sTag + "\"."); String sSampleImageUrl; if ( TryGetSampleImageUrl(sTag, sApiKey, oRequestStatistics, out sSampleImageUrl) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue( oKeyValuePair.Value, NodeXLGraphMLUtil.VertexImageFileID, sSampleImageUrl); } } }
protected override void AddVertexImageAttribute(XmlNode oVertexXmlNode, Vertex<String> oVertex, GraphMLXmlDocument oGraphMLXmlDocument) { // add picture if (oVertex.Attributes.ContainsKey("photo_50") && oVertex.Attributes["photo_50"] != null) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, ImageFileID, oVertex.Attributes["photo_50"].ToString()); } }
TryAppendVertexXmlNode ( String sUserName, XmlNode oEntryXmlNode, GraphMLXmlDocument oGraphMLXmlDocument, Dictionary<String, XmlNode> oUserNameDictionary ) { Debug.Assert( !String.IsNullOrEmpty(sUserName) ); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oUserNameDictionary != null); XmlNode oVertexXmlNode; if ( oUserNameDictionary.TryGetValue(sUserName, out oVertexXmlNode) ) { return (false); } oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode(sUserName); oUserNameDictionary.Add(sUserName, oVertexXmlNode); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuTextID, "Open YouTube Page for This Person"); oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuActionID, String.Format(WebPageUrlPattern, sUserName)); return (true); }
AppendVertexTooltipXmlNodes ( GraphMLXmlDocument graphMLXmlDocument, Dictionary<String, TwitterUser> userIDDictionary ) { Debug.Assert(graphMLXmlDocument != null); Debug.Assert(userIDDictionary != null); foreach (TwitterUser twitterUser in userIDDictionary.Values) { // The tooltip is the user's screen name followed by the first // tweet returned by Twitter. ICollection<TwitterStatus> statuses = twitterUser.Statuses; String firstStatus = statuses.Count > 0 ? statuses.First().Text : String.Empty; // The Excel template doesn't wrap long tooltip text. Break the // status into lines so the entire tooltip will show in the graph // pane. firstStatus = StringUtil.BreakIntoLines(firstStatus, 30); String toolTip = String.Format( "{0}\n\n{1}" , twitterUser.ScreenName, firstStatus ); graphMLXmlDocument.AppendGraphMLAttributeValue( twitterUser.VertexXmlNode, VertexToolTipID, toolTip); } }
AddUserUserCommentsEdges ( ref GraphMLXmlDocument oGraphMLXmlDocument, Dictionary<string, Dictionary<string, List<string>>> commentersComments, JSONObject streamPosts, Dictionary<string, Dictionary<string, JSONObject>> attributeValues ) { Dictionary<string, List<string>> postCommenters = new Dictionary<string,List<string>>(); XmlNode oEdgeXmlNode = null; List<string> postsIntersection = new List<string>(); string posts = ""; //Create the Post-Commenter relationship from commenterComments foreach(JSONObject item in streamPosts.Array) { foreach (KeyValuePair<string, Dictionary<string, List<string>>> kvp in commentersComments) { if (kvp.Value.ContainsKey(item.Dictionary["post_id"].String)) { try { postCommenters[item.Dictionary["post_id"].String].Add(kvp.Key); } catch (KeyNotFoundException e) { List<string> tmp = new List<string>(); tmp.Add(kvp.Key); postCommenters.Add(item.Dictionary["post_id"].String, tmp); } } } } //Add Edges foreach (KeyValuePair<string, List<string>> kvp in postCommenters) { for (int i = 0; i < kvp.Value.Count - 1; i++) { for (int j = i + 1; j < kvp.Value.Count; j++) { //Sometimes a commenter or liker can be another fan page and this is not a user if (!usersDisplayName.ContainsKey(kvp.Value[i]) || !usersDisplayName.ContainsKey(kvp.Value[j])) continue; oEdgeXmlNode = oGraphMLXmlDocument.AppendEdgeXmlNode(usersDisplayName[kvp.Value[i]], usersDisplayName[kvp.Value[j]]); postsIntersection = commentersComments[kvp.Value[i]].Keys.Intersect(commentersComments[kvp.Value[j]].Keys).ToList(); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oEdgeXmlNode, "e_weight", postsIntersection.Count); string[] postsToJoin = (from p in postsIntersection select new { Post = streamPosts.Array.Single(x => x.Dictionary["post_id"].String.Equals(p)).Dictionary["message"].String }).Select(x => x.Post).ToArray(); posts = String.Join("\n\n", postsToJoin); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oEdgeXmlNode, "post", posts); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oEdgeXmlNode, "Relationship", "Co-Commenter"); } } } }
AppendVertexTooltipXmlNodes ( GraphMLXmlDocument oGraphMLXmlDocument, XmlNode oVertexXmlNode, String sVertex, String sDisplayString ) { // The NodeXL template doesn't wrap long tooltip text. Break the // status into lines so the entire tooltip will show in the graph // pane. sDisplayString = StringUtil.BreakIntoLines(sDisplayString, 30); String sTooltip = String.Format( "{0}\n\n{1}" , sVertex, sDisplayString ); oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, TooltipID, sTooltip); }
AddPostVertices ( ref GraphMLXmlDocument oGraphMLXmlDocument, JSONObject streamPosts ) { XmlNode oVertexXmlNode; //Add nodes (posts) foreach (JSONObject ob in streamPosts.Array) { oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode(ob.Dictionary["post_id"].String); //Add tooltip AppendVertexTooltipXmlNodes(oGraphMLXmlDocument, oVertexXmlNode, ob.Dictionary["post_id"].String, ob.Dictionary["message"].String); //Add attributes oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "type", "2"); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, LabelColumnName, ob.Dictionary["message"].String); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "content", ob.Dictionary["message"].String); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, MenuTextID, "Open Facebook Page for This Post"); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, MenuActionID, ob.Dictionary["permalink"].String); //If the post contains a link to a video, photo, document etc //and it has a picture, use it as the post image if(ob.Dictionary["attachment"].Dictionary.ContainsKey("media") && ob.Dictionary["attachment"].Dictionary["media"].Array.Length>0) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "Image", ob.Dictionary["attachment"].Dictionary["media"].Array[0].Dictionary["src"].String); } } }
AddLikerVertices ( ref GraphMLXmlDocument oGraphMLXmlDocument, Dictionary<string, List<string>> likersPost, Dictionary<string, Dictionary<string, JSONObject>> attributeValues, Dictionary<string, List<Dictionary<string, object>>> statusUpdates, Dictionary<string, List<Dictionary<string, object>>> wallPosts ) { XmlNode oVertexXmlNode; likersWithNoAttributes = new Dictionary<string, string>(); //Add nodes foreach (var item in likersPost) { if (!attributeValues.ContainsKey(item.Key)) { //This means that the liker is not a user but a page //FacebookAPI fb = new FacebookAPI(); JSONObject pageObject = CallGraphAPIWithRelogin("/" + item.Key); if (!pageObject.IsDictionary) continue; string vertexName = ManageDisplayNames(pageObject.Dictionary["name"].String, item.Key); if (String.IsNullOrEmpty(vertexName)) continue; oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode(vertexName); //Add tooltip AppendVertexTooltipXmlNodes(oGraphMLXmlDocument, oVertexXmlNode, pageObject.Dictionary["name"].String, ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "type", "1"); if (pageObject.Dictionary.ContainsKey("picture")) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "Image", pageObject.Dictionary["picture"].String); } oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "v_weight", item.Value.Count); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, MenuTextID, "Open Facebook Page for This User"); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, MenuActionID, FacebookURL + item.Key); //Add this user to the appropriate "no attributes" dictionary //likersWithNoAttributes.Add(item.Key, pageObject.Dictionary["name"].String); } else { oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode(usersDisplayName[item.Key]); //Add tooltip AppendVertexTooltipXmlNodes(oGraphMLXmlDocument, oVertexXmlNode, usersDisplayName[item.Key], ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "type", "1"); //Add attributes for the actual user AddAttributes(ref oGraphMLXmlDocument, ref oVertexXmlNode, attributeValues[item.Key] ); if (attributeValues[item.Key].ContainsKey("pic_small") && attributeValues[item.Key]["pic_small"] != null) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "Image", attributeValues[item.Key]["pic_small"].String); } oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "v_weight", item.Value.Count); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, MenuTextID, "Open Facebook Page for This User"); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, MenuActionID, FacebookURL + item.Key); } if (bGetStatusUpdates) { AddStatusUpdates(ref oGraphMLXmlDocument, ref oVertexXmlNode, item.Key, statusUpdates ); } if (bGetWallPosts) { AddWallPosts(ref oGraphMLXmlDocument, ref oVertexXmlNode, item.Key, wallPosts ); } } }
AddWallPosts ( ref GraphMLXmlDocument oGraphMLXmlDocument, ref XmlNode oVertexXmlNode, string userID, Dictionary<string, List<Dictionary<string, object>>> wallPosts ) { List<Dictionary<string, object>>.Enumerator en; string currentWallPost = ""; string currentWallTags = ""; //Add wall posts if (wallPosts.ContainsKey(userID)) { en = wallPosts[userID].GetEnumerator(); currentWallPost = ""; currentWallTags = ""; while (en.MoveNext() && currentWallPost.Length < 8000) { if (((JSONObject)en.Current["message"]).String.Equals("")) continue; currentWallPost += (en.Current.ContainsKey("name")?((JSONObject)en.Current["name"]).String:"[No Name]") + ": " + ((JSONObject)en.Current["message"]).String + "\n\n"; //Add tags if (en.Current["message_tags"] is List<JSONObject>) { foreach (JSONObject ob in (List<JSONObject>)en.Current["message_tags"]) { currentWallTags += ob.String + ","; } currentWallTags = currentWallTags.Remove(currentWallTags.Length - 1); currentWallTags += "\n\n"; } } oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "wall_posts", currentWallPost); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "wall_tags", currentWallTags); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "wall_urls", GetURLs(currentWallPost, ' ')); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "wall_hashtags", GetHashtags(currentWallPost, ' ')); } }
AppendLatitudeAndLongitudeGraphMLAttributeValues ( GraphMLXmlDocument graphMLXmlDocument, XmlNode edgeOrVertexXmlNode, String latitude, String longitude ) { Debug.Assert(graphMLXmlDocument != null); Debug.Assert(edgeOrVertexXmlNode != null); if ( !String.IsNullOrEmpty(latitude) ) { graphMLXmlDocument.AppendGraphMLAttributeValue( edgeOrVertexXmlNode, LatitudeID, latitude); } if ( !String.IsNullOrEmpty(longitude) ) { graphMLXmlDocument.AppendGraphMLAttributeValue( edgeOrVertexXmlNode, LongitudeID, longitude); } }
AppendTweetedSearchTermGraphMLAttributeValue ( GraphMLXmlDocument graphMLXmlDocument, TwitterUser twitterUser, Boolean userTweetedSearchTerm ) { Debug.Assert(graphMLXmlDocument != null); Debug.Assert(twitterUser != null); graphMLXmlDocument.AppendGraphMLAttributeValue( twitterUser.VertexXmlNode, VertexTweetedSearchTermID, userTweetedSearchTerm ? "Yes" : "No"); }
AppendInReplyToStatusIDGraphMLAttributeValue ( GraphMLXmlDocument graphMLXmlDocument, XmlNode edgeOrVertexXmlNode, String inReplyToStatusID ) { Debug.Assert(graphMLXmlDocument != null); Debug.Assert(edgeOrVertexXmlNode != null); if ( !String.IsNullOrEmpty(inReplyToStatusID) ) { // Precede the ID with a single quote to force Excel to treat the // ID as text. Otherwise, it formats the ID, which is a large // number, in scientific notation. graphMLXmlDocument.AppendGraphMLAttributeValue( edgeOrVertexXmlNode, InReplyToStatusIDID, "'" + inReplyToStatusID); } }
AppendUserInformationGraphMLAttributeValues ( String sUserID, XmlNode oVertexXmlNode, GraphMLXmlDocument oGraphMLXmlDocument, String sApiKey, RequestStatistics oRequestStatistics ) { Debug.Assert( !String.IsNullOrEmpty(sUserID) ); Debug.Assert(oVertexXmlNode != null); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert( !String.IsNullOrEmpty(sApiKey) ); Debug.Assert(oRequestStatistics != null); AssertValid(); String sUrl = GetFlickrMethodUrl( "flickr.people.getInfo", sApiKey, GetUserIDUrlParameter(sUserID) ); XmlDocument oXmlDocument; if ( !TryGetXmlDocument(sUrl, oRequestStatistics, out oXmlDocument) ) { // Ignore errors. The user information isn't critical. return; } const String XPathRoot = "rsp/person/"; AppendStringGraphMLAttributeValue(oXmlDocument, XPathRoot + "realname/text()", null, oGraphMLXmlDocument, oVertexXmlNode, RealNameID); AppendInt32GraphMLAttributeValue(oXmlDocument, XPathRoot + "photos/count/text()", null, oGraphMLXmlDocument, oVertexXmlNode, TotalPhotosID); String sIsProfessional; if ( XmlUtil2.TrySelectSingleNodeAsString(oXmlDocument, XPathRoot + "@ispro", null, out sIsProfessional) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, IsProfessionalID, (sIsProfessional == "0") ? "No" : "Yes" ); } // Get the URL to the user's buddy icon, which is explained here: // // http://www.flickr.com/services/api/misc.buddyicons.html Int32 iIconServer, iIconFarm; String sBuddyIconUrl; if ( XmlUtil2.TrySelectSingleNodeAsInt32(oXmlDocument, XPathRoot + "@iconserver", null, out iIconServer) && XmlUtil2.TrySelectSingleNodeAsInt32(oXmlDocument, XPathRoot + "@iconfarm", null, out iIconFarm) && iIconServer > 0 ) { sBuddyIconUrl = String.Format( "http://farm{0}.static.flickr.com/{1}/buddyicons/{2}.jpg" , iIconFarm, iIconServer, sUserID ); } else { sBuddyIconUrl = "http://www.flickr.com/images/buddyicon.jpg"; } oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, NodeXLGraphMLUtil.VertexImageFileID, sBuddyIconUrl); if ( AppendStringGraphMLAttributeValue(oXmlDocument, XPathRoot + "photosurl/text()", null, oGraphMLXmlDocument, oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuActionID)) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuTextID, "Open Flickr Page for This Person"); } }
AppendVertexXmlNode ( String sTag, GraphMLXmlDocument oGraphMLXmlDocument, Dictionary<String, XmlNode> oTagDictionary ) { Debug.Assert( !String.IsNullOrEmpty(sTag) ); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oTagDictionary != null); if ( !oTagDictionary.ContainsKey(sTag) ) { XmlNode oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode( sTag); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, NodeXLGraphMLUtil.VertexLabelID, sTag); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuTextID, "Open Flickr Page for This Tag"); oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, NodeXLGraphMLUtil.VertexMenuActionID, String.Format( "http://www.flickr.com/photos/tags/{0}/" , UrlUtil.EncodeUrlParameter(sTag) ) ); oTagDictionary.Add(sTag, oVertexXmlNode); } }
GetUserNetworkRecursive ( String sUserID, String sScreenName, WhatToInclude eWhatToInclude, Boolean bIncludeContactsThisCall, NetworkLevel eNetworkLevel, Int32 iMaximumPerRequest, String sApiKey, Int32 iRecursionLevel, GraphMLXmlDocument oGraphMLXmlDocument, Dictionary<String, XmlNode> oUserIDDictionary, RequestStatistics oRequestStatistics ) { Debug.Assert( !String.IsNullOrEmpty(sUserID) ); Debug.Assert( !String.IsNullOrEmpty(sScreenName) ); Debug.Assert(eNetworkLevel == NetworkLevel.One || eNetworkLevel == NetworkLevel.OnePointFive || eNetworkLevel == NetworkLevel.Two); Debug.Assert(iMaximumPerRequest > 0); Debug.Assert( !String.IsNullOrEmpty(sApiKey) ); Debug.Assert(iRecursionLevel == 1 || iRecursionLevel == 2); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oUserIDDictionary != null); Debug.Assert(oRequestStatistics != null); AssertValid(); /* Here is what this method should do, based on the eNetworkLevel and iRecursionLevel parameters. eNetworkLevel |One | OnePointFive | Two ---|------------------| ------------------| ----------------- i 1 |Add all vertices. | Add all vertices. | Add all vertices. R | | | e |Add all edges. | Add all edges. | Add all edges. c | | | u |Do not recurse. | Recurse. | Recurse. r | | | s ---|------------------|-------------------|------------------ i 2 |Impossible. | Do not add | Add all vertices. o | | vertices. | n | | | L | | Add edges only if | Add all edges. e | | vertices are | v | | already included. | e | | | l | | Do not recurse. | Do not recurse. | | | ---|------------------|-------------------|------------------ */ Boolean bNeedToRecurse = GetNeedToRecurse(eNetworkLevel, iRecursionLevel); Boolean bNeedToAppendVertices = GetNeedToAppendVertices(eNetworkLevel, iRecursionLevel); List<String> oUserIDsToRecurse = new List<String>(); ReportProgressForContactsOrCommenters(sScreenName, bIncludeContactsThisCall); Boolean bThisUserAppended = false; foreach ( XmlNode oChildXmlNode in GetContactsOrCommentersEnumerator( sUserID, bIncludeContactsThisCall, iMaximumPerRequest, oGraphMLXmlDocument, sApiKey, oRequestStatistics) ) { String sOtherScreenName, sOtherUserID; if ( !XmlUtil2.TrySelectSingleNodeAsString(oChildXmlNode, bIncludeContactsThisCall ? "@username" : "@authorname", null, out sOtherScreenName) || !XmlUtil2.TrySelectSingleNodeAsString(oChildXmlNode, bIncludeContactsThisCall ? "@nsid" : "@author", null, out sOtherUserID) ) { continue; } if (!bThisUserAppended) { // Append a vertex node for this request's user. // // This used to be done after the foreach loop, which avoided // the need for a "bThisUserAppended" flag. That caused the // following bug: If a YouTube error occurred within // EnumerateXmlNodes() after some edges had been added, and the // user decided to import the resulting partial network, the // GraphML might contain edges that referenced "this user" // without containing a vertex for "this user." That is an // illegal state for GraphML, which the ExcelTemplate project // caught and reported as an error. TryAppendVertexXmlNode(sUserID, sScreenName, oGraphMLXmlDocument, oUserIDDictionary); bThisUserAppended = true; } if (bNeedToAppendVertices) { if ( TryAppendVertexXmlNode(sOtherUserID, sOtherScreenName, oGraphMLXmlDocument, oUserIDDictionary) && bNeedToRecurse ) { oUserIDsToRecurse.Add(sOtherUserID); } } if ( bNeedToAppendVertices || oUserIDDictionary.ContainsKey(sOtherUserID) ) { // Append an edge node and optional attributes. XmlNode oEdgeXmlNode; if (bIncludeContactsThisCall) { oEdgeXmlNode = NodeXLGraphMLUtil.AppendEdgeXmlNode( oGraphMLXmlDocument, sScreenName, sOtherScreenName, "Contact"); } else { // (Note the swapping of screen names in the commenter // case.) oEdgeXmlNode = NodeXLGraphMLUtil.AppendEdgeXmlNode( oGraphMLXmlDocument, sOtherScreenName, sScreenName, "Commenter"); UInt32 uCommentDateUtc; if ( XmlUtil2.TrySelectSingleNodeAsUInt32(oChildXmlNode, "@datecreate", null, out uCommentDateUtc) ) { DateTime oCommentDateUtc = DateTimeUtil2.UnixTimestampToDateTimeUtc( uCommentDateUtc); oGraphMLXmlDocument.AppendGraphMLAttributeValue( oEdgeXmlNode, CommentDateUtcID, ExcelDateTimeUtil.DateTimeToStringLocale1033( oCommentDateUtc, ExcelColumnFormat.DateAndTime) ); } AppendStringGraphMLAttributeValue(oChildXmlNode, "@permalink", null, oGraphMLXmlDocument, oEdgeXmlNode, CommentUrlID); } } } if (bNeedToRecurse) { foreach (String sUserIDToRecurse in oUserIDsToRecurse) { XmlNode oVertexXmlNode = oUserIDDictionary[sUserIDToRecurse]; String sScreenNameToRecurse = GetScreenNameFromVertexXmlNode( oVertexXmlNode); GetUserNetworkRecursive(sUserIDToRecurse, sScreenNameToRecurse, eWhatToInclude, bIncludeContactsThisCall, eNetworkLevel, iMaximumPerRequest, sApiKey, 2, oGraphMLXmlDocument, oUserIDDictionary, oRequestStatistics); } } }
AppendLatestStatusInformationFromValueDictionary ( Dictionary<String, Object> oStatusValueDictionary, GraphMLXmlDocument oGraphMLXmlDocument, TwitterUser oTwitterUser, Boolean bIncludeLatestStatus, Boolean bExpandLatestStatusUrls ) { Debug.Assert(oStatusValueDictionary != null); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oTwitterUser != null); AssertValid(); TwitterStatus oTwitterStatus; if ( !TwitterStatus.TryFromStatusValueDictionary( oStatusValueDictionary, bExpandLatestStatusUrls, out oTwitterStatus) ) { return; } XmlNode oVertexXmlNode = oTwitterUser.VertexXmlNode; if (bIncludeLatestStatus) { // Add the status to the vertex XML node. oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, TwitterGraphMLUtil.VertexLatestStatusID, oTwitterStatus.Text); String sLatestStatusUrls = oTwitterStatus.Urls; if ( !String.IsNullOrEmpty(sLatestStatusUrls) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, TwitterGraphMLUtil.VertexLatestStatusUrlsID, sLatestStatusUrls); oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, TwitterGraphMLUtil.VertexLatestStatusDomainsID, TwitterGraphMLUtil.UrlsToDomains(sLatestStatusUrls) ); } String sLatestStatusHashtags = oTwitterStatus.Hashtags; if ( !String.IsNullOrEmpty(sLatestStatusHashtags) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, TwitterGraphMLUtil.VertexLatestStatusHashtagsID, sLatestStatusHashtags); } if ( !String.IsNullOrEmpty(oTwitterStatus.ParsedDateUtc) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue( oVertexXmlNode, TwitterGraphMLUtil.VertexLatestStatusDateUtcID, oTwitterStatus.ParsedDateUtc); } TwitterGraphMLUtil. AppendLatitudeAndLongitudeGraphMLAttributeValues( oGraphMLXmlDocument, oVertexXmlNode, oTwitterStatus.Latitude, oTwitterStatus.Longitude); TwitterGraphMLUtil.AppendInReplyToStatusIDGraphMLAttributeValue( oGraphMLXmlDocument, oVertexXmlNode, oTwitterStatus.InReplyToStatusID); } oTwitterUser.Statuses.Add(oTwitterStatus); }
AppendRepliesToAndMentionsEdgeXmlNode ( GraphMLXmlDocument graphMLXmlDocument, String screenName1, String screenName2, String relationship, TwitterStatus twitterStatus, Boolean includeStatus ) { Debug.Assert(graphMLXmlDocument != null); Debug.Assert( !String.IsNullOrEmpty(screenName1) ); Debug.Assert( !String.IsNullOrEmpty(screenName2) ); Debug.Assert( !String.IsNullOrEmpty(relationship) ); Debug.Assert(twitterStatus != null); XmlNode edgeXmlNode = NodeXLGraphMLUtil.AppendEdgeXmlNode( graphMLXmlDocument, screenName1, screenName2, relationship); String statusDateUtc = twitterStatus.ParsedDateUtc; Boolean hasStatusDateUtc = !String.IsNullOrEmpty(statusDateUtc); if (hasStatusDateUtc) { // The status's date is the relationship date. graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, EdgeRelationshipDateUtcID, statusDateUtc); } if (includeStatus) { String statusText = twitterStatus.Text; graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, EdgeStatusID, statusText); String urls = twitterStatus.Urls; if ( !String.IsNullOrEmpty(urls) ) { graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, EdgeStatusUrlsID, urls); graphMLXmlDocument.AppendGraphMLAttributeValue( edgeXmlNode, EdgeStatusDomainsID, UrlsToDomains(urls) ); } if ( !String.IsNullOrEmpty(twitterStatus.Hashtags) ) { graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, EdgeStatusHashtagsID, twitterStatus.Hashtags); } if (hasStatusDateUtc) { graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, EdgeStatusDateUtcID, statusDateUtc); } graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, EdgeStatusWebPageUrlID, FormatStatusWebPageUrl(screenName1, twitterStatus) ); AppendLatitudeAndLongitudeGraphMLAttributeValues( graphMLXmlDocument, edgeXmlNode, twitterStatus.Latitude, twitterStatus.Longitude); // Precede the ID with a single quote to force Excel to treat the // ID as text. Otherwise, it formats the ID, which is a large // number, in scientific notation. graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode, NodeXLGraphMLUtil.ImportedIDID, "'" + twitterStatus.ID); AppendInReplyToStatusIDGraphMLAttributeValue(graphMLXmlDocument, edgeXmlNode, twitterStatus.InReplyToStatusID); } }
AppendDoubleGraphMLAttributeValue ( XmlNode oXmlNodeToSelectFrom, String sXPath, XmlNamespaceManager oXmlNamespaceManager, GraphMLXmlDocument oGraphMLXmlDocument, XmlNode oEdgeOrVertexXmlNode, String sGraphMLAttributeID ) { Debug.Assert(oXmlNodeToSelectFrom != null); Debug.Assert( !String.IsNullOrEmpty(sXPath) ); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oEdgeOrVertexXmlNode != null); Debug.Assert( !String.IsNullOrEmpty(sGraphMLAttributeID) ); AssertValid(); Double dAttributeValue; if ( XmlUtil2.TrySelectSingleNodeAsDouble(oXmlNodeToSelectFrom, sXPath, oXmlNamespaceManager, out dAttributeValue) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue( oEdgeOrVertexXmlNode, sGraphMLAttributeID, dAttributeValue); return (true); } return (false); }
TryAppendVertexXmlNode ( String screenName, String userID, GraphMLXmlDocument graphMLXmlDocument, Dictionary<String, TwitterUser> userIDDictionary, out TwitterUser twitterUser ) { Debug.Assert( !String.IsNullOrEmpty(screenName) ); Debug.Assert( !String.IsNullOrEmpty(userID) ); Debug.Assert(graphMLXmlDocument != null); Debug.Assert(userIDDictionary != null); twitterUser = null; if ( userIDDictionary.TryGetValue(userID, out twitterUser) ) { // A vertex XML node already exists. return (false); } XmlNode vertexXmlNode = graphMLXmlDocument.AppendVertexXmlNode( screenName); twitterUser = new TwitterUser(screenName, vertexXmlNode); userIDDictionary.Add(userID, twitterUser); graphMLXmlDocument.AppendGraphMLAttributeValue(vertexXmlNode, NodeXLGraphMLUtil.VertexMenuTextID, "Open Twitter Page for This Person"); graphMLXmlDocument.AppendGraphMLAttributeValue( vertexXmlNode, NodeXLGraphMLUtil.VertexMenuActionID, String.Format(TwitterApiUrls.UserWebPageUrlPattern, screenName) ); return (true); }
AppendGraphMLAttributeValues ( IMetadataProvider oEdgeOrVertex, GraphMLXmlDocument oGraphMLXmlDocument, XmlNode oEdgeOrVertexXmlNode, String [] asAttributeNames, String AttributeIDPrefix ) { Debug.Assert(oEdgeOrVertex != null); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oEdgeOrVertexXmlNode != null); Debug.Assert(asAttributeNames != null); Debug.Assert( !String.IsNullOrEmpty(AttributeIDPrefix) ); AssertValid(); foreach (String sAttributeName in asAttributeNames) { Object oAttributeValue; // Note that the value type isn't checked. Whatever type it is, // it gets converted to a string. if (oEdgeOrVertex.TryGetValue(sAttributeName, out oAttributeValue) && oAttributeValue != null) { oGraphMLXmlDocument.AppendGraphMLAttributeValue( oEdgeOrVertexXmlNode, AttributeIDPrefix + sAttributeName, oAttributeValue.ToString() ); } } }
AppendUserStatisticsFromValueDictionary ( Dictionary<String, Object> userValueDictionary, GraphMLXmlDocument graphMLXmlDocument, TwitterUser twitterUser ) { Debug.Assert(userValueDictionary != null); Debug.Assert(graphMLXmlDocument != null); Debug.Assert(twitterUser != null); XmlNode vertexXmlNode = twitterUser.VertexXmlNode; AppendValueFromValueDictionary(userValueDictionary, "friends_count", graphMLXmlDocument, vertexXmlNode, VertexFollowedID); AppendValueFromValueDictionary(userValueDictionary, "followers_count", graphMLXmlDocument, vertexXmlNode, VertexFollowersID); AppendValueFromValueDictionary(userValueDictionary, "statuses_count", graphMLXmlDocument, vertexXmlNode, VertexStatusesID); AppendValueFromValueDictionary(userValueDictionary, "favourites_count", graphMLXmlDocument, vertexXmlNode, VertexFavoritesID); AppendValueFromValueDictionary(userValueDictionary, "description", graphMLXmlDocument, vertexXmlNode, VertexDescriptionID); AppendValueFromValueDictionary(userValueDictionary, "location", graphMLXmlDocument, vertexXmlNode, VertexLocationID); AppendValueFromValueDictionary(userValueDictionary, "url", graphMLXmlDocument, vertexXmlNode, VertexUrlID); AppendValueFromValueDictionary(userValueDictionary, "time_zone", graphMLXmlDocument, vertexXmlNode, VertexTimeZoneID); AppendValueFromValueDictionary(userValueDictionary, "utc_offset", graphMLXmlDocument, vertexXmlNode, VertexUtcOffsetID); String joinedDateUtc; if ( TwitterJsonUtil.TryGetJsonValueFromDictionary(userValueDictionary, "created_at", out joinedDateUtc) ) { graphMLXmlDocument.AppendGraphMLAttributeValue( vertexXmlNode, VertexJoinedDateUtcID, TwitterDateParser.ParseTwitterDate(joinedDateUtc) ); } }
AppendEdgesFromDictionary ( Dictionary< String, LinkedList<String> > oDictionary, GraphMLXmlDocument oGraphMLXmlDocument, String sRelationship, String sKeyAttributeID ) { Debug.Assert(oDictionary != null); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert( !String.IsNullOrEmpty(sRelationship) ); Debug.Assert( !String.IsNullOrEmpty(sKeyAttributeID) ); AssertValid(); // For each key... foreach (KeyValuePair< String, LinkedList<String> > oKeyValuePair in oDictionary) { String sKey = oKeyValuePair.Key; // For each video ID that has the key... LinkedList<String> oVideoIDsWithThisKey = oKeyValuePair.Value; for ( LinkedListNode<String> oVideoIDWithThisKey = oVideoIDsWithThisKey.First; oVideoIDWithThisKey != null; oVideoIDWithThisKey = oVideoIDWithThisKey.Next ) { // For each of the subsequent video IDs in the LinkedList that // have the key... for ( LinkedListNode<String> oSubsequentVideoIDWithThisKey = oVideoIDWithThisKey.Next; oSubsequentVideoIDWithThisKey != null; oSubsequentVideoIDWithThisKey = oSubsequentVideoIDWithThisKey.Next ) { XmlNode oEdgeXmlNode = NodeXLGraphMLUtil.AppendEdgeXmlNode( oGraphMLXmlDocument, oVideoIDWithThisKey.Value, oSubsequentVideoIDWithThisKey.Value, sRelationship); oGraphMLXmlDocument.AppendGraphMLAttributeValue( oEdgeXmlNode, sKeyAttributeID, sKey); } } } }
AppendValueFromValueDictionary ( Dictionary<String, Object> valueDictionary, String name, GraphMLXmlDocument graphMLXmlDocument, XmlNode edgeOrVertexXmlNode, String graphMLAttributeID ) { Debug.Assert(valueDictionary != null); Debug.Assert( !String.IsNullOrEmpty(name) ); Debug.Assert(graphMLXmlDocument != null); Debug.Assert(edgeOrVertexXmlNode != null); Debug.Assert( !String.IsNullOrEmpty(graphMLAttributeID) ); String value; if ( TwitterJsonUtil.TryGetJsonValueFromDictionary( valueDictionary, name, out value) ) { graphMLXmlDocument.AppendGraphMLAttributeValue( edgeOrVertexXmlNode, graphMLAttributeID, value); return (true); } return (false); }
AppendYouTubeDateGraphMLAttributeValue ( XmlNode oXmlNodeToSelectFrom, String sXPath, XmlNamespaceManager oXmlNamespaceManager, GraphMLXmlDocument oGraphMLXmlDocument, XmlNode oVertexXmlNode, String sGraphMLAttributeID ) { Debug.Assert(oXmlNodeToSelectFrom != null); Debug.Assert( !String.IsNullOrEmpty(sXPath) ); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oVertexXmlNode != null); Debug.Assert( !String.IsNullOrEmpty(sGraphMLAttributeID) ); AssertValid(); String sYouTubeDate; if ( XmlUtil2.TrySelectSingleNodeAsString(oXmlNodeToSelectFrom, sXPath, oXmlNamespaceManager, out sYouTubeDate) ) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, sGraphMLAttributeID, FormatYouTubeDate(sYouTubeDate) ); return (true); } return (false); }
AddAttributes ( ref GraphMLXmlDocument oGraphMLXmlDocument, ref XmlNode oVertexXmlNode, Dictionary<string, JSONObject> attributeValues ) { string attributeValue = ""; foreach (KeyValuePair<string, JSONObject> kvp in attributeValues) { //Facebook's TOS doesn't allow the redistribution of UIDs //so they are not included in the network. //They are used as keys for the dictionaries. if (kvp.Key.Equals("uid") || kvp.Key.Equals("display_name")) { continue; } if (kvp.Value == null || (kvp.Value.String == null && !kvp.Value.IsDictionary)) { attributeValue = ""; } else if (kvp.Key.Equals("hometown_location")) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "hometown", kvp.Value.Dictionary.ContainsKey("name") ? kvp.Value.Dictionary["name"].String : ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "hometown_city", kvp.Value.Dictionary.ContainsKey("city") ? kvp.Value.Dictionary["city"].String : ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "hometown_state", kvp.Value.Dictionary.ContainsKey("state") ? kvp.Value.Dictionary["state"].String : ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "hometown_country", kvp.Value.Dictionary.ContainsKey("country") ? kvp.Value.Dictionary["country"].String : ""); } else if (kvp.Key.Equals("current_location")) { oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "location", kvp.Value.Dictionary.ContainsKey("name") ? kvp.Value.Dictionary["name"].String : ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "location_city", kvp.Value.Dictionary.ContainsKey("city") ? kvp.Value.Dictionary["city"].String : ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "location_state", kvp.Value.Dictionary.ContainsKey("state") ? kvp.Value.Dictionary["state"].String : ""); oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, "location_country", kvp.Value.Dictionary.ContainsKey("country") ? kvp.Value.Dictionary["country"].String : ""); } else { if (kvp.Key.Equals("profile_update_time")) { attributeValue = DateUtil.ConvertToDateTime(kvp.Value.Integer).ToString(); } else if (kvp.Value.String.Length > 8000) { attributeValue = kvp.Value.String.Remove(8000); } else { attributeValue = kvp.Value.String; } oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode, kvp.Key, attributeValue); } } }