//************************************************************************* // Method: AppendEdgeXmlNode() // /// <summary> /// Appends an edge XML node to a GraphML document. /// </summary> /// /// <param name="oGraphMLXmlDocument"> /// GraphMLXmlDocument being populated. /// </param> /// /// <param name="sVertex1ID"> /// ID of the edge's first vertex. /// </param> /// /// <param name="sVertex2ID"> /// ID of the edge's second vertex. /// </param> /// /// <param name="sRelationship"> /// The value of the edge's RelationshipID GraphML-attribute. /// </param> /// /// <returns> /// The new edge XML node. /// </returns> //************************************************************************* protected XmlNode 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); }
//************************************************************************* // Method: GetRelatedTagsRecursive() // /// <summary> /// Recursively gets a tag's related tags. /// </summary> /// /// <param name="sTag"> /// Tag to get related tags for. /// </param> /// /// <param name="eWhatToInclude"> /// Specifies what should be included in the network. /// </param> /// /// <param name="eNetworkLevel"> /// Network level to include. Must be NetworkLevel.One, OnePointFive, or /// Two. /// </param> /// /// <param name="sApiKey"> /// Flickr API key. /// </param> /// /// <param name="iRecursionLevel"> /// Recursion level for this call. Must be 1 or 2. Gets incremented when /// recursing. /// </param> /// /// <param name="oGraphMLXmlDocument"> /// GraphMLXmlDocument being populated. /// </param> /// /// <param name="oTagDictionary"> /// The key is the tag name and the value is the corresponding GraphML XML /// node that represents the tag. /// </param> /// /// <param name="oRequestStatistics"> /// A <see cref="RequestStatistics" /> object that is keeping track of /// requests made while getting the network. /// </param> //************************************************************************* protected void GetRelatedTagsRecursive( String sTag, WhatToInclude eWhatToInclude, NetworkLevel eNetworkLevel, String sApiKey, Int32 iRecursionLevel, GraphMLXmlDocument oGraphMLXmlDocument, Dictionary<String, XmlNode> oTagDictionary, RequestStatistics oRequestStatistics ) { Debug.Assert( !String.IsNullOrEmpty(sTag) ); Debug.Assert(eNetworkLevel == NetworkLevel.One || eNetworkLevel == NetworkLevel.OnePointFive || eNetworkLevel == NetworkLevel.Two); Debug.Assert( !String.IsNullOrEmpty(sApiKey) ); Debug.Assert(iRecursionLevel == 1 || iRecursionLevel == 2); Debug.Assert(oGraphMLXmlDocument != null); Debug.Assert(oTagDictionary != 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); ReportProgress("Getting tags related to \"" + sTag + "\"."); String sUrl = GetFlickrMethodUrl( "flickr.tags.getRelated", sApiKey, "&tag=" + UrlUtil.EncodeUrlParameter(sTag) ); XmlDocument oXmlDocument; try { oXmlDocument = GetXmlDocument(sUrl, oRequestStatistics); } catch (Exception oException) { // If the exception is not a WebException or XmlException, or if // none of the network has been obtained yet, throw the exception. if (!ExceptionIsWebOrXml(oException) || !oGraphMLXmlDocument.HasVertexXmlNode) { throw oException; } return; } // The document consists of a single "tags" node with zero or more // "tag" child nodes. String sOtherTag = null; XmlNodeList oTagNodes = oXmlDocument.DocumentElement.SelectNodes( "tags/tag"); if (oTagNodes.Count > 0) { AppendVertexXmlNode(sTag, oGraphMLXmlDocument, oTagDictionary); } foreach (XmlNode oTagNode in oTagNodes) { sOtherTag = XmlUtil2.SelectRequiredSingleNodeAsString(oTagNode, "text()", null); if (bNeedToAppendVertices) { AppendVertexXmlNode(sOtherTag, oGraphMLXmlDocument, oTagDictionary); } if ( bNeedToAppendVertices || oTagDictionary.ContainsKey(sOtherTag) ) { oGraphMLXmlDocument.AppendEdgeXmlNode(sTag, sOtherTag); } } if (bNeedToRecurse) { foreach (XmlNode oTagNode in oTagNodes) { sOtherTag = XmlUtil2.SelectRequiredSingleNodeAsString(oTagNode, "text()", null); GetRelatedTagsRecursive(sOtherTag, eWhatToInclude, eNetworkLevel, sApiKey, 2, oGraphMLXmlDocument, oTagDictionary, oRequestStatistics); } } }
//************************************************************************* // Method: SaveGraphCore() // /// <summary> /// Saves graph data to a stream. /// </summary> /// /// <param name="graph"> /// Graph to save. /// </param> /// /// <param name="stream"> /// Stream to save the graph data to. /// </param> /// /// <remarks> /// This method saves <paramref name="graph" /> to <paramref /// name="stream" />. It does not close <paramref name="stream" />. /// /// <para> /// The arguments have already been checked for validity. /// </para> /// /// </remarks> //************************************************************************* protected override void SaveGraphCore( IGraph graph, Stream stream ) { Debug.Assert(graph != null); Debug.Assert(stream != null); AssertValid(); GraphMLXmlDocument oGraphMLXmlDocument = new GraphMLXmlDocument( graph.Directedness == GraphDirectedness.Directed); String [] asEdgeAttributeNames = ( String[] )graph.GetRequiredValue( ReservedMetadataKeys.AllEdgeMetadataKeys, typeof( String[] ) ); String [] asVertexAttributeNames = ( String[] )graph.GetRequiredValue( ReservedMetadataKeys.AllVertexMetadataKeys, typeof( String[] ) ); // Define the Graph-ML attributes. const String VertexAttributeIDPrefix = "V-"; const String EdgeAttributeIDPrefix = "E-"; foreach (String sVertexAttributeName in asVertexAttributeNames) { oGraphMLXmlDocument.DefineGraphMLAttribute(false, VertexAttributeIDPrefix + sVertexAttributeName, sVertexAttributeName, "string", null); } foreach (String sEdgeAttributeName in asEdgeAttributeNames) { oGraphMLXmlDocument.DefineGraphMLAttribute(true, EdgeAttributeIDPrefix + sEdgeAttributeName, sEdgeAttributeName, "string", null); } // Add the vertices and their Graph-ML attribute values. foreach (IVertex oVertex in graph.Vertices) { XmlNode oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode( oVertex.Name); AppendGraphMLAttributeValues(oVertex, oGraphMLXmlDocument, oVertexXmlNode, asVertexAttributeNames, VertexAttributeIDPrefix); } // Add the edges and their Graph-ML attribute values. foreach (IEdge oEdge in graph.Edges) { IVertex [] oVertices = oEdge.Vertices; XmlNode oEdgeXmlNode = oGraphMLXmlDocument.AppendEdgeXmlNode( oVertices[0].Name, oVertices[1].Name); AppendGraphMLAttributeValues(oEdge, oGraphMLXmlDocument, oEdgeXmlNode, asEdgeAttributeNames, EdgeAttributeIDPrefix); } oGraphMLXmlDocument.Save(stream); }