Example #1
0
        public override void LoadFromXML(XmlElement xmlElement, LTSCanvas canvas)
        {
            base.LoadFromXML(xmlElement, canvas);
            try
            {
                Kind        = (ChannelKind)Enum.Parse(typeof(ChannelKind), xmlElement.GetAttribute(XmlTag.ATTR_CHANNEL_KIND), true);
                Type        = (ChannelType)int.Parse(xmlElement.GetAttribute(XmlTag.ATTR_LINK_TYPE));
                SendingRate = int.Parse(xmlElement.GetAttribute(XmlTag.ATTR_MAX_SENDING_RATE));

                string cgnLevel = xmlElement.GetAttribute(XmlTag.ATTR_CONGESTION_LEVEL);
                CongestionLevel = (CGNLevel)Enum.Parse(typeof(CGNLevel), cgnLevel);

                // Add probability of choosing path leading to congestion
                ProbabilityPathCongestion = double.Parse(xmlElement.GetAttribute(XmlTag.ATTR_PROB_PATH_CONGESTION));

                ID = xmlElement.GetAttribute(XmlTag.ATTR_ID);

                if (ID != null && ID.Length == 0)
                {
                    ID = null;
                }
            }
            catch (Exception ex)
            {
                DevLog.d(TAG, ex.ToString());
            }
        }
Example #2
0
        public override void LoadFromXml(XmlElement element)
        {
            // Base load first
            base.LoadFromXml(element);
            try
            {
                NodeType = (SensorType)int.Parse(element.GetAttribute(XmlTag.ATTR_SENSOR_TYPE));
                if (NodeType == SensorType.Source)
                {
                    initialState = true;
                }

                ID = int.Parse(element.GetAttribute(XmlTag.ATTR_ID));

                SendingRate    = int.Parse(element.GetAttribute(XmlTag.ATTR_MAX_SENDING_RATE));
                ProcessingRate = int.Parse(element.GetAttribute(XmlTag.ATTR_MAX_PROCESSING_RATE));

                string cngLevel = element.GetAttribute(XmlTag.ATTR_CONGESTION_LEVEL);
                CongestionLevel = (CGNLevel)Enum.Parse(typeof(CGNLevel), cngLevel);
            }
            catch (Exception ex)
            {
                DevLog.d(TAG, ex.ToString());
            }
        }
Example #3
0
        private void btn_apply_Click(object sender, EventArgs e)
        {
            do
            {
                int fixedVal = 0;
                EditPropertyType editType = (EditPropertyType)Enum.Parse(typeof(EditPropertyType), cmxBufferType.Text, true);

                try
                {
                    fixedVal = Int32.Parse(txtFixed.Text);
                }
                catch (Exception ex)
                {
                    DevLog.d(TAG, ex.ToString());
                    MessageBox.Show("Value format is incorrect!", "Parse error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                String       columnEdited = null;
                DataGridView gridView     = null;
                switch (editType)
                {
                // For sensor
                case EditPropertyType.SensorMaxSendingRate:
                    columnEdited = "SendingRate";
                    gridView     = mGridSensor;
                    break;

                case EditPropertyType.SensorMaxProcessingRate:
                    columnEdited = "ProcessingRate";
                    gridView     = mGridSensor;
                    break;

                // For channel
                case EditPropertyType.ChannelMaxSendingRate:
                    columnEdited = "SendingRate";
                    gridView     = mGridChannel;
                    break;

                default:
                    break;
                }

                if (columnEdited == null || gridView == null)
                {
                    break;
                }

                changeValue(fixedVal, columnEdited, gridView);
            } while (false);
        }
Example #4
0
        public PNGenerationHelper(string name, EditorTabItem tabItem) : base(name, tabItem)
        {
            try
            {
                WSNTabItem wsnTabItem = (WSNTabItem)tabItem;
                mCanvas   = wsnTabItem.getAllCanvas();
                mDocPNRes = wsnTabItem.PNRes;

                // Get extend information
                mExtendInfo = wsnTabItem.mExtendInfo;

                initXML();
                mLoaded = true;
            }
            catch (Exception ex)
            {
                DevLog.d(TAG, "Can not read wsn document");
            }
        }
Example #5
0
        private void btnOK_Click(object sender, EventArgs e)
        {
            do
            {
                // not multicast mode
                if (!mMode.Equals(NetMode.MULTICAST))
                {
                    break;
                }

                string[] sConn = txtSensorsConn.Text.Trim().Split(',');

                if (sConn.Length < 2)
                {
                    break;
                }

                string toId = ((WSNSensor)mChannel.To).ID.ToString();
                mChannel.SubIdList.Clear();

                foreach (string item in sConn)
                {
                    if (toId.Equals(item))
                    {
                        continue;
                    }

                    try
                    {
                        mChannel.SubIdList.Add(Int32.Parse(item));
                    }
                    catch (Exception ex) {
                        DevLog.d(TAG, "Error: " + ex.ToString());
                    }
                }
            } while (false);
        }
Example #6
0
        /// <summary>
        /// Get the PN xml data
        /// </summary>
        /// <param name="PNRes">PN XML resource document</param>
        /// <param name="pnId">Id (Name) of the PN model</param>
        /// <param name="itemId">Sensor/Channel item Id</param>
        /// <param name="xShift"></param>
        /// <param name="yShift"></param>
        /// <returns></returns>
        public static WSNPNData GetPNXml(XmlDocument PNRes, string id, string pnId, string itemId, float xShift, float yShift, double probPathCongestion = 0.0)
        {
            WSNPNData data = null;
            string    tmp;

            do
            {
                if (PNRes == null)
                {
                    break;
                }

                if (pnId == null || pnId.Length == 0)
                {
                    break;
                }

                // find the sensor PN model
                string query = string.Format("//{0}[@{1}='{2}']", XmlTag.TAG_MODEL, XmlTag.ATTR_NAME, pnId);

                XmlElement pnModel = null;
                try
                {
                    pnModel = (XmlElement)PNRes.SelectSingleNode(query).CloneNode(true);
                }
                catch
                {
                    DevLog.d(TAG, "Can not find the sensor model node in resource!");
                    break;
                }
                XmlNodeList nodeList = null;


                #region Update node name
                // update the name of these nodes
                if (itemId == null || itemId.Length == 0)
                {
                    DevLog.d(TAG, "Sensor ID is invalid: " + itemId);
                    break;
                }

                // node Place, Transition
                {
                    string[] nodes = new []
                    {
                        XmlTag.TAG_PLACE,
                        XmlTag.TAG_TRANSITION,
                    };
                    foreach (string node in nodes)
                    {
                        nodeList = pnModel.GetElementsByTagName(node);
                        if (nodeList == null || nodeList.Count == 0)
                        {
                            continue;
                        }

                        foreach (XmlElement xml in nodeList)
                        {
                            tmp = xml.GetAttribute(XmlTag.ATTR_NAME);
                            xml.SetAttribute(XmlTag.ATTR_NAME, tmp + itemId);
                            xml.SetAttribute(XmlTag.TAG_REFERENCE_ID, id);

                            // Add probability of choosing path leading to congestion
                            // For transition that is named ChannelF_T only
                            Regex channelReg      = new Regex(@"Channel([0-9])_([0-9])");
                            Match matchChannelReg = channelReg.Match(xml.GetAttribute(XmlTag.ATTR_NAME));
                            if (matchChannelReg.Success)
                            {
                                xml.SetAttribute(XmlTag.ATTR_PROB_PATH_CONGESTION, probPathCongestion.ToString());
                            }
                        }
                    }
                }

                // node Arc
                {
                    nodeList = pnModel.GetElementsByTagName(XmlTag.TAG_ARC);
                    foreach (XmlElement xml in nodeList)
                    {
                        tmp = xml.GetAttribute(XmlTag.TAG_ARC_PRO_FROM);
                        xml.SetAttribute(XmlTag.TAG_ARC_PRO_FROM, tmp + itemId);

                        tmp = xml.GetAttribute(XmlTag.TAG_ARC_PRO_TO);
                        xml.SetAttribute(XmlTag.TAG_ARC_PRO_TO, tmp + itemId);
                    }
                }
                #endregion

                #region Combine the returned data
                data             = new WSNPNData();
                data.nodeId      = itemId;
                data.places      = (XmlElement)pnModel.GetElementsByTagName(XmlTag.TAG_PLACES)[0];
                data.transitions = (XmlElement)pnModel.GetElementsByTagName(XmlTag.TAG_TRANSITIONS)[0];
                data.arcs        = (XmlElement)pnModel.GetElementsByTagName(XmlTag.TAG_ARCS)[0];
                #endregion

                #region Update node position
                do
                {
                    if (xShift <= 0 && yShift <= 0)
                    {
                        break;
                    }

                    XmlElement[] elements = new XmlElement[]
                    {
                        data.places,
                        data.transitions,
                        data.arcs,
                    };

                    query = string.Format("//{0}", XmlTag.TAG_POSITION);

                    float xPos;
                    float yPos;
                    foreach (XmlElement node in elements)
                    {
                        nodeList = node.SelectNodes(query);

                        foreach (XmlElement ele in nodeList)
                        {
                            xPos = -1;
                            yPos = -1;
                            try
                            {
                                xPos = float.Parse(ele.GetAttribute(XmlTag.ATTR_POSITION_X));
                            }
                            catch { }
                            try
                            {
                                yPos = float.Parse(ele.GetAttribute(XmlTag.ATTR_POSITION_Y));
                            }
                            catch { }
                            if (xPos < 0 && yPos < 0)
                            {
                                continue;
                            }

                            xPos += xShift;
                            yPos += yShift;

                            ele.SetAttribute(XmlTag.ATTR_POSITION_X, xPos.ToString());
                            ele.SetAttribute(XmlTag.ATTR_POSITION_Y, yPos.ToString());
                        }
                    }
                } while (false);
                #endregion

                #region Save the position
                XmlElement xNode;

                data.inNode = new NodeInfo();

                string inName  = pnModel.GetAttribute(XmlTag.TAG_MODEL_PRO_IN);
                string outName = pnModel.GetAttribute(XmlTag.TAG_MODEL_PRO_OUT);

                if (inName == null || inName.Length == 0)
                {
                    inName = "Input";
                }
                query = string.Format("//*[@{0}='{1}{2}']/{3}", XmlTag.ATTR_NAME, inName, itemId, XmlTag.TAG_POSITION);
                xNode = (XmlElement)pnModel.SelectSingleNode(query);
                if (xNode != null)
                {
                    data.inNode.name = inName;
                    data.inNode.pos  = new Position();
                    try
                    {
                        data.inNode.pos.x = float.Parse(xNode.GetAttribute(XmlTag.ATTR_POSITION_X));
                        data.inNode.pos.y = float.Parse(xNode.GetAttribute(XmlTag.ATTR_POSITION_Y));
                    }
                    catch { }
                }

                data.outNode = new NodeInfo();
                if (outName == null || outName.Length == 0)
                {
                    outName = "Output";
                }
                query = string.Format("//*[@{0}='{1}{2}']/{3}", XmlTag.ATTR_NAME, outName, itemId, XmlTag.TAG_POSITION);
                xNode = (XmlElement)pnModel.SelectSingleNode(query);
                if (xNode != null)
                {
                    data.outNode.name = outName;
                    data.outNode.pos  = new Position();
                    try
                    {
                        data.outNode.pos.x = float.Parse(xNode.GetAttribute(XmlTag.ATTR_POSITION_X));
                        data.outNode.pos.y = float.Parse(xNode.GetAttribute(XmlTag.ATTR_POSITION_Y));
                    }
                    catch { }
                }
                #endregion
            } while (false);

            return(data);
        }
Example #7
0
        /// <summary>
        /// Generate PN xml file from KWSN model
        /// </summary>
        /// <param name="abstractSensor">if Sensors are abstracted</param>
        /// <param name="abstractChannel">if Channel are abstracted</param>
        /// <returns>PN xml</returns>
        public override XmlDocument GenerateXML(params bool[] values)
        {
            do
            {
                if (values == null || values.Count() != 3)
                {
                    DevLog.e(TAG, "Incorrect input params");
                    break;
                }

                bool abstractSensor  = values[0];
                bool abstractChannel = values[1];
                bool improved        = values[2];

                bool       blError = false;
                XmlElement models  = mDocOut.CreateElement(XmlTag.TAG_MODELS);
                mXRoot.AppendChild(models);

                foreach (WSNCanvas canvas in mCanvas)
                {
                    List <WSNSensor>  sensors              = new List <WSNSensor>();  // sensors list from canvas
                    List <WSNChannel> channels             = new List <WSNChannel>(); // channel list from canvas
                    StringBuilder     ltlSensorCongestion  = new StringBuilder();     // LTL for check on sensor
                    StringBuilder     ltlChannelCongestion = new StringBuilder();     // LTL for check on channel
                    int          maxSensorId    = 0;
                    List <Int32> sensorCheckIds = new List <Int32>();

                    foreach (LTSCanvas.CanvasItemData item in canvas.itemsList) // get the sensors list
                    {
                        if (item.Item is WSNSensor)
                        {
                            WSNSensor add = (WSNSensor)item.Item;
                            add.locateX = item.Item.X / 120;
                            add.locateY = item.Item.Y / 120;

                            if (mMinX == 0 || add.locateX < mMinX)
                            {
                                mMinX = add.locateX;
                            }
                            if (mMinY == 0 || add.locateY < mMinY)
                            {
                                mMinY = add.locateY;
                            }

                            sensors.Add(add.Clone());
                            if (add.ID > maxSensorId)
                            {
                                maxSensorId = add.ID;
                            }

                            // Append LTL for sensor congestion
                            if (abstractSensor || add.NodeType != SensorType.Intermediate)
                            {
                                continue;
                            }
                            sensorCheckIds.Add(add.ID);
                        }
                    }

                    // Add LTL check congestion on sensor
                    int interCnt = sensorCheckIds.Count;
                    if (interCnt > 0)
                    {
                        ltlSensorCongestion.Append("#assert System |= []!(");
                        for (int i = 0; i < interCnt - 1; i++)
                        {
                            ltlSensorCongestion.Append(String.Format("Congestion{0} || ", sensorCheckIds[i]));
                        }
                        ltlSensorCongestion.Append(String.Format("Congestion{0});", sensorCheckIds[interCnt - 1]));
                    }

                    // Get the channels list
                    foreach (Route route in canvas.diagramRouter.routes)
                    {
                        if (route is WSNChannel)
                        {
                            WSNChannel channel = (WSNChannel)route;
                            channel.Type = getChannelType(Build.mMode);
                            channels.Add(channel.Clone());
                        }
                    }

                    XmlElement topology = mDocOut.CreateElement(XmlTag.TAG_TOPOLOGY);
                    topology.SetAttribute(XmlTag.ATTR_mID, mExtendInfo.mID.ToString());
                    topology.SetAttribute(XmlTag.ATTR_NUMOFSENSORS, mExtendInfo.mNumberSensor.ToString());
                    topology.SetAttribute(XmlTag.ATTR_NUMOFPACKETS, mExtendInfo.mNumberPacket.ToString());
                    topology.SetAttribute(XmlTag.ATTR_AVGBUFFER, mExtendInfo.mSensorMaxBufferSize.ToString());
                    topology.SetAttribute(XmlTag.TAG_MODE, Build.mMode.ToString());
                    topology.SetAttribute(XmlTag.TAG_ABSTRACTEDLEVEL, (abstractSensor ? "0" : "1") + (abstractChannel ? "0" : "1"));

                    foreach (WSNSensor sensor in sensors) // append sensor to topology
                    {
                        topology.AppendChild(sensor.WriteToXml(mDocOut));
                    }

                    foreach (WSNChannel channel in channels) // append channel to topology
                    {
                        topology.AppendChild(channel.WriteToXml(mDocOut));
                    }

                    XmlElement model       = mDocOut.CreateElement(XmlTag.TAG_MODEL);
                    XmlElement places      = mDocOut.CreateElement(XmlTag.TAG_PLACES);
                    XmlElement transitions = mDocOut.CreateElement(XmlTag.TAG_TRANSITIONS);
                    XmlElement arcs        = mDocOut.CreateElement(XmlTag.TAG_ARCS);

                    models.AppendChild(model);
                    model.AppendChild(topology);
                    model.AppendChild(places);
                    model.AppendChild(transitions);
                    model.AppendChild(arcs);

                    do
                    {
                        WSNPNData data      = null;
                        float     xStartPos = 0;
                        float     yStartPos = 0;

                        Hashtable mapData = new Hashtable();
                        bool      localSensorAbstract;
                        foreach (WSNSensor sensor in sensors)
                        {
                            ////// Force keep source sensor in case unicast or multicast
                            //localSensorAbstract = abstractSensor;
                            //if (sensor.NodeType == SensorType.Source
                            //    && abstractSensor && (Build.mMode == NetMode.UNICAST || Build.mMode == NetMode.MULTICAST))
                            //    localSensorAbstract = false;

                            data = sensor.GeneratePNXml(mDocPNRes, sensor.ID.ToString(), abstractSensor, sensor.locateX - mMinX, sensor.locateY - mMinY);
                            if (data == null)
                            {
                                DevLog.e(TAG, "Failed to generate the sensor PN xml nodes");
                                blError = true;
                                break;
                            }

                            mapData[sensor.ID] = data;
                            xStartPos         += XPOSITION_SHIFT;

                            // 20151113-lqv-change model
                            // Embed code for sensor
                            BuildUtils.embedCodeToSensor(data, sensor, channels, abstractSensor);
                            addPNData(data, ref places, ref transitions, ref arcs);

                            // Then find the channel connected with this sensor
                            foreach (WSNChannel channel in channels)
                            {
                                WSNSensor sensorFrom = (WSNSensor)channel.From;
                                if (sensorFrom.ID != sensor.ID)
                                {
                                    continue;
                                }

                                // compute positon for channel
                                xStartPos = (channel.From.AbsoluteX + channel.To.AbsoluteX) / 240;
                                yStartPos = (channel.From.AbsoluteY + channel.To.AbsoluteY) / 240;

                                data = channel.GeneratePNXml(mDocPNRes, channel.ID, abstractChannel, xStartPos - mMinX, yStartPos - mMinY, channel.ProbabilityPathCongestion);
                                if (data == null)
                                {
                                    DevLog.d(TAG, "Failed to generate the sensor PN xml nodes");
                                    blError = true;
                                    break;
                                }

                                mapData[channel.ID] = data;
                                xStartPos          += XPOSITION_SHIFT; // Shift x position
                                yStartPos          += YPOSITION_SHIFT; // Shift y position

                                // 20151113-lqv-changle model
                                BuildUtils.embedCodeToChannel(data, channel, abstractChannel, abstractSensor);
                                addPNData(data, ref places, ref transitions, ref arcs);
                            } // foreach

                            if (blError == true)
                            {
                                break;
                            }
                        } // foreach

                        if (blError == true)
                        {
                            break;
                        }


                        LocalNetwork localNetwork = new LocalNetwork(mapData, abstractSensor, abstractChannel, sensors, channels);
                        switch (Build.mMode)  // build connector by mode
                        {
                        case NetMode.BROADCAST:
                            BuildUtils.buildConnOutSensorBR(mDocOut, transitions, places, arcs, localNetwork);
                            if (improved)
                            {
                                BuildUtils.buildConnInSensorImprove(mDocOut, transitions, places, arcs, localNetwork);
                                break;
                            }
                            BuildUtils.buildConnInSensor(mDocOut, transitions, places, arcs, localNetwork);
                            break;

                        case NetMode.UNICAST:
                            BuildUtils.buildConnOutSensorUN(mDocOut, transitions, places, arcs, localNetwork);
                            // Not support improved in unicast mode
                            BuildUtils.buildConnInSensor(mDocOut, transitions, places, arcs, localNetwork);
                            break;

                        case NetMode.MULTICAST:
                            BuildUtils.buildConnOutSensorMC(mDocOut, transitions, places, arcs, localNetwork);
                            BuildUtils.buildConnInSensor(mDocOut, transitions, places, arcs, localNetwork);
                            //if (improved)
                            //{
                            //    BuildUtils.buildConnInSensorImprove(mDocOut, transitions, places, arcs, localNetwork);
                            //    break;
                            //}
                            //BuildUtils.buildConnInSensor(mDocOut, transitions, places, arcs, localNetwork);
                            break;

                        default:
                            break;
                        }

                        #region Update model properties
                        // update the property
                        model.SetAttribute(XmlTag.ATTR_NAME, canvas.ProcessName);
                        model.SetAttribute(XmlTag.ATTR_PRO_PARAM, "");
                        model.SetAttribute(XmlTag.ATTR_ZOOM, "1");
                        model.SetAttribute(XmlTag.TAG_MODEL_PRO_PCOUNTER, "0");
                        model.SetAttribute(XmlTag.TAG_MODEL_PRO_TCOUNTER, "0");
                        #endregion

                        mDocOut.Save(mFileName); // save document
                    } while (false);

                    // Add LTL check congestion on channel
                    if (abstractChannel == false && channels.Count > 0)
                    {
                        ltlChannelCongestion.Append("#assert System |= []!(");
                        for (int i = 0; i < channels.Count - 1; i++)
                        {
                            ltlChannelCongestion.AppendFormat("Congestion{0} || ", channels[i].ID);
                        }
                        ltlChannelCongestion.AppendFormat("Congestion{0});", channels[channels.Count - 1].ID);
                    }

                    // add declaration
                    mDeclaration.InnerXml = String.Format(mDocPNRes.GetElementsByTagName(
                                                              XmlTag.TAG_DECLARATION)[0].InnerXml,
                                                          BuildUtils.buildDeclaration(mExtendInfo, sensors, channels),
                                                          ltlSensorCongestion.ToString(),   // LTL for check on sensor
                                                          ltlChannelCongestion.ToString()); // LTL for check on channel
                }
            } while (false);

            return(mDocOut);
        }
Example #8
0
        private void createLink(List <String> Pathfull, string lType, string lFrom, string lTo, string lX, string lY, string lWidth, XmlTextWriter writer, string lSendingRate, string CGNLink)
        {
            //Start Link
            writer.WriteStartElement(XmlTag.TAG_CHANNEL);
            writer.WriteAttributeString(XmlTag.ATTR_CHANNEL_KIND, lType);
            writer.WriteAttributeString(XmlTag.ATTR_LINK_TYPE, "0");
            writer.WriteAttributeString(XmlTag.ATTR_MAX_SENDING_RATE, lSendingRate);
            writer.WriteAttributeString(XmlTag.ATTR_ID, lFrom + "_" + lTo);
            writer.WriteAttributeString(XmlTag.ATTR_CONGESTION_LEVEL, CGNLink);

            //From
            writer.WriteStartElement(XmlTag.TAG_CHANNEL_FROM);
            writer.WriteString("Sensor " + lFrom);
            writer.WriteEndElement();

            //To
            writer.WriteStartElement(XmlTag.TAG_CHANNEL_TO);
            writer.WriteString("Sensor " + lTo);
            writer.WriteEndElement();

            //Path
            if (lType == "Virtual")
            {
                DevLog.d(TAG, "=============Export XML===============");
                DevLog.d(TAG, "From: " + lFrom + " to: " + lTo);
                writer.WriteStartElement(XmlTag.TAG_PATH);
                for (int i = 0; i < Pathfull.Count; i++)
                {
                    string temp = "";
                    string path = "";
                    path += Pathfull[i].ToString();
                    char[]   d  = new char[] { ';' };
                    string[] s1 = Pathfull[i].Split(d, StringSplitOptions.RemoveEmptyEntries);
                    for (int p = 0; p < s1.Length; p++)
                    {
                        temp += s1[p];
                        char[]   c  = new char[] { '-' };
                        string[] s2 = temp.Split(c, StringSplitOptions.RemoveEmptyEntries);
                        if ((s2[0].ToString() == lFrom) && (s2[s2.Length - 1].ToString() == lTo))
                        {
                            DevLog.d(TAG, "" + path);
                            writer.WriteString(path);
                            break;
                        }
                    }
                }
                writer.WriteEndElement();
            }

            //Select
            writer.WriteStartElement("Select");
            writer.WriteEndElement();

            //Event
            writer.WriteStartElement("Event");
            writer.WriteEndElement();

            //ClockGuard
            writer.WriteStartElement("ClockGuard");
            writer.WriteEndElement();

            //Guard
            writer.WriteStartElement(XmlTag.TAG_GUARD);
            writer.WriteEndElement();

            //Program
            writer.WriteStartElement(XmlTag.TAG_PROGRAM);
            writer.WriteEndElement();

            //ClockReset
            writer.WriteStartElement("ClockReset");
            writer.WriteEndElement();

            //Label
            writer.WriteStartElement(XmlTag.TAG_LABEL);
            writer.WriteStartElement(XmlTag.TAG_POSITION);
            writer.WriteAttributeString(XmlTag.ATTR_POSITION_X, lX);
            writer.WriteAttributeString(XmlTag.ATTR_POSITION_Y, lY);
            writer.WriteAttributeString(XmlTag.ATTR_POSITION_WIDTH, lWidth);
            writer.WriteEndElement();
            writer.WriteEndElement();

            //End </Link>
            writer.WriteEndElement();
        }