Example #1
0
        public void ExtractNetworkFromXml(XmlDocument xDoc)
        {
            //create a dictionary of connected graphs
            //go through the document creating each node and its connections
            //have a dictionary of nodes to see if we saw this node already
            //if so do not recreate it.
            //if not create the node and it's connections
            //once the graph is built pick a node and start moving through them
            //to extract minimal spanning tree(s)
            //then walk the tree to evaluate node rules

            XmlNodeList objectNodes       = xDoc.SelectNodes("/mxGraphModel/root/object[not(@redDot)]");
            XmlNodeList zoneNodes         = xDoc.SelectNodes("//*[@zone=\"1\"]");
            XmlNodeList mxCellLinkObjects = xDoc.SelectNodes("/mxGraphModel/root/object[mxCell/@edge='1']");
            XmlNodeList mxCellLinks       = xDoc.SelectNodes("//*[@edge=\"1\"]");

            XmlNodeList mxCellLayers = xDoc.SelectNodes("//*[@parent=\"0\" and @id]");

            foreach (XmlNode layer in mxCellLayers)
            {
                string id = layer.Attributes["id"].Value;
                layers.Add(id, new NetworkLayer()
                {
                    ID        = id,
                    LayerName = layer.Attributes["value"] != null ? layer.Attributes["value"].Value : Constants.DEFAULT_LAYER_NAME,
                    Visible   = layer.Attributes["visible"] != null ? (layer.Attributes["visible"].Value == "0" ? false : true) : true
                });
            }

            foreach (XmlNode node in zoneNodes)
            {
                //determine if it is an edge or a node
                //if it is an node look it up(should be new)
                //and create it
                //if it is an edge then we need to save it until all the nodes are created
                //once we have them all start connecting everything up.

                //if it is a zone then just skip it
                if (((XmlElement)node).HasAttribute("zone"))
                {
                    string zone = node.Attributes["id"].Value;

                    zones.Add(zone, new NetworkZone()
                    {
                        ID       = zone,
                        ZoneType = node.Attributes["ZoneType"].Value,
                        SAL      = node.Attributes["SAL"].Value
                    });
                }
            }


            foreach (XmlNode node in objectNodes)
            {
                //determine if it is an edge or a node
                //if it is an node look it up(should be new)
                //and create it
                //if it is an edge then we need to save it until all the nodes are created
                //once we have them all start connecting everything up.

                //if it is a zone then just skip it
                if (((XmlElement)node).HasAttribute("zone"))
                {
                    continue;
                }


                //do a little preprocessing to get the attribute values
                var styleString = node.FirstChild.Attributes["style"].Value;


                // if it is a group then skip it
                if (styleString.Split(';').Contains("group"))
                {
                    continue;
                }


                int nodeType = 0;

                string imgPath;
                if (DrawIOParsingHelps.DecodeQueryParameters(styleString.Replace("image;", "")).TryGetValue("image", out imgPath))
                {
                    if (!imageToTypePath.TryGetValue(imgPath.Replace("img/cset/", ""), out nodeType))
                    {
                    }
                }
                else
                {
                    //I think we can assume
                    nodeType = 49;// "MSC";
                }

                //get the parent value if it is in the layers dictionary then set the
                //visible value to the value of the parent
                //else set it to visible
                string       layername = node.FirstChild.Attributes["parent"].Value;
                NetworkLayer layer;
                bool         IsVisible = true;
                if (layers.TryGetValue(layername, out layer))
                {
                    if (!layer.Visible)
                    {
                        //if it is not visible skip it.
                        continue;
                    }
                }

                //extract the geometry to a point on the component
                NetworkGeometry geometry = new NetworkGeometry(node.FirstChild.FirstChild);

                NetworkComponent dnode;
                string           id = node.Attributes["id"].Value;
                if (nodes.TryGetValue(id, out dnode))
                {
                    //this should never happen we should never have a duplicate id
                }
                else
                {
                    dnode = new NetworkComponent()
                    {
                        ComponentGuid       = ((XmlElement)node).HasAttribute("ComponentGuid") ? Guid.Parse(node.Attributes["ComponentGuid"].Value) : new Guid(),
                        ID                  = node.Attributes["id"].Value,
                        ComponentName       = ((XmlElement)node).HasAttribute("label") ? node.Attributes["label"].Value : "",
                        Component_Symbol_Id = nodeType,
                        //ComponentType = nodeType,
                        IsVisible = IsVisible,
                        Parent_id = layername,
                        Geometry  = geometry
                    };

                    NetworkZone myzone;
                    if (zones.TryGetValue(layername, out myzone))
                    {
                        dnode.Zone = myzone;
                    }
                    else
                    {
                        dnode.Zone = defaultZone;
                    }
                    nodes.Add(id, dnode);
                }
            }

            //the mxCellLinks list also has the objects
            //so we keep track of the child id's and
            //if we see them again in the raw links
            //then just skip it.
            foreach (XmlNode node in mxCellLinkObjects)
            {
                XmlElement xNode = (XmlElement)node;
                var        link  = new NetworkLink();
                foreach (XmlAttribute a in node.Attributes)
                {
                    link.setValue(a.Name, a.Value);
                }
                Links.Add(link);
                var childnode = ((XmlElement)xNode.FirstChild);
                //find each node
                //add them to each other
                if (childnode.HasAttribute("source") && childnode.HasAttribute("target"))
                {
                    NetworkComponent start  = findNode(childnode.Attributes["source"].Value);
                    NetworkComponent target = findNode(childnode.Attributes["target"].Value);
                    //map any other attributes
                    link.SourceComponent = start;
                    link.TargetComponent = target;
                    start?.AddEdge(target, link);
                    target?.AddEdge(start, link);
                }
            }
            foreach (XmlNode node in mxCellLinks)
            {
                XmlElement xNode = (XmlElement)node;
                if (((XmlElement)xNode.ParentNode).Name == "object")
                {
                    continue;//skip it
                }
                //find each node
                //add them to each other
                if (xNode.HasAttribute("source") && xNode.HasAttribute("target"))
                {
                    NetworkComponent start  = findNode(node.Attributes["source"].Value);
                    NetworkComponent target = findNode(node.Attributes["target"].Value);
                    //map any other attributes
                    var link = new NetworkLink();
                    link.ID = xNode.Attributes["id"].Value;
                    link.SourceComponent = start;
                    link.TargetComponent = target;
                    Links.Add(link);
                    start?.AddEdge(target, link);
                    target?.AddEdge(start, link);
                }
            }
            this.nodes = PostProcessConnectors.RemoveConnectors(nodes);
        }