Click here to Skip to main content
13,146,365 members (44,365 online)
Click here to Skip to main content
Add your own
alternative version

Stats

86.4K views
2.5K downloads
109 bookmarked
Posted 28 Jul 2008

Firefox Bookmark Manager by C# and XML

, 24 Sep 2008
Rate this:
Please Sign up or sign in to vote.
With KingMark you can exchange your bookmarks between Firefox and IE
Firefox bookmark manager

Firefox bookmark manager

Introduction

This is a simple Firefox bookmark manager. With KingMark you can import, manage and export Firefox bookmarks as a HTML or *.url or XML file. KingMark works with XML, first converts the Firefox bookmark file into the XML file and then converts it into the HTML file.

Using the Code

Creating XML file

KingMark creates an XML file with unique names for each node. For example, this is a node in the XML file:

<NODE9 NAME="FireFox" ADD_DATE="1213909970" 

		LAST_MODIFIED="1220234375" DESC="">
    <BOOKMARK10 NAME="Mozilla - Home" 

		HREF="http://en-us.www.mozilla.com/en-US/" 

		  SHORTCUTURL="mozila" DESC="" 

        ADD_DATE="1183006386" LAST_MODIFIED="1220234476" 

        ICON_URI="" ICON="" />

    <BOOKMARK11 NAME="mozillaZine Forums" 

		HREF="http://forums.mozillazine.org/index.php" 

        SHORTCUTURL="" DESC="" ADD_DATE="1214351419" LAST_MODIFIED="1220233809" 

        ICON_URI="" ICON="" />

    <BOOKMARK12 NAME="Mozilla Support" 

		HREF="http://support.mozilla.com/tiki-my_tiki.php#content_forum" 

        SHORTCUTURL="" DESC="" ADD_DATE="1214143305" LAST_MODIFIED="1220233808" 

        ICON_URI="" ICON="" />

    <BOOKMARK13 NAME="AfzoneHaye FF" 

		HREF="http://addons.mozillafirefox.ir/" SHORTCUTURL="" 

        DESC="" ADD_DATE="1218070432" LAST_MODIFIED="1219953174" 

        ICON_URI="" ICON="" />

</NODE9>

As you can see, each node has a unique name so I used these names for denominating TreeView nodes' names. Well by this denomination we can find each node in an XML file and TreeView control easily.

I saved the biggest node number (for example : <BOOKMARK13 ... />) in an attribute (ELEMENTS) in the root node. With this attribute we can find the latest number used in denomination and we start denominating after it. And with OPTIMIZE XML FILE, KingMark arranges the XML elements .

First: KingMark converts the FF BookMark file (HTML file) to the List<string> object (intermediate code)

You can see the intermediate code with checking Trace in Settings.

When you check Trace, the private void trace(List<string> list) method creates trace.txt beside your FF bookmark file that includes intermediate code for generating an XML file.

After KingMark converts the List<string> object to the XML file with the System.Xml.XmlWriter class and the below method:

private void ListToXml(List<string> list)
{
    string name = "";
    string href = "";
    string icon = "";
    string iconUrl = "";
    string desc = "";
    string keyWords = "";
    string addDate = "";
    string lastModified = "";
    try
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        //settings.NewLineOnAttributes = true;
        settings.Encoding = Encoding.UTF8;
        settings.ConformanceLevel = ConformanceLevel.Document;
        System.Xml.XmlWriter Writer;
        Writer = XmlWriter.Create(temporaryFileName, settings);
        Writer.WriteStartDocument();
        Writer.WriteComment(XmlDescription);
        Writer.WriteStartElement(rootNodeName);
        Writer.WriteAttributeString("ELEMENTS", list.Count.ToString());
        for (int i = 1; i < list.Count; i++)
        {
            //Nodes separator
            if (Regex.IsMatch(list[i], @"\<HR\>"))
            {
                //Writer.WriteStartElement("HR");
                //Writer.WriteEndElement();
                continue;
            }
            else if (Regex.IsMatch(list[i], @"\<NODE\>"))
            {
                //node's NAME
                name = Regex.Match(list[i - 1].Trim(), "NAME=\"[^\"]*\"").ToString();
                name = Regex.Replace(name, "NAME|\"|=", "");
                //node's DESC
                desc = Regex.Match(list[i - 1].Trim(), 
					"DESC=\"[^\"]*\"").ToString();
                desc = Regex.Replace(desc, "DESC|\"|=", "");
                //node's ADD_DATE
                addDate = Regex.Match(list[i - 1].Trim(), 
					"ADD_DATE=\"[^\"]*\"").ToString();
                addDate = Regex.Replace(addDate, "ADD_DATE|\"|=", "");
                //node's LAST_MODIFIED
                lastModified = Regex.Match(list[i - 1].Trim(), 
					"LAST_MODIFIED=\"[^\"]*\"").ToString();
                lastModified = Regex.Replace(lastModified, 
					"LAST_MODIFIED|\"|=", "");
                //\\
                Writer.WriteStartElement("NODE" + i.ToString());
                Writer.WriteAttributeString("NAME", name);
                Writer.WriteAttributeString("ADD_DATE", addDate);
                Writer.WriteAttributeString("LAST_MODIFIED", lastModified);
                Writer.WriteAttributeString("DESC", desc);
            }
            else if (list[i].Trim() == "</NODE>")
            {
                if (i + 1 != list.Count)
                Writer.WriteEndElement();
            }
            else if (!Regex.IsMatch(list[i + 1], @"\<NODE\>"))
            {
                //bookmark's name extracting
                name = Regex.Match(list[i], "NAME=\"[^\"]*\"").ToString();
                name = Regex.Replace(name, "NAME|\"|=", "");
                //bookmark's address extracting
                href = Regex.Match(list[i].Trim(), 
					"HREF=\"[^\"]*\"").ToString();
                href = Regex.Replace(href, "HREF|\"|=", "");
                //bookmark's icon's URL extracting
                iconUrl = Regex.Match(list[i].Trim(), 
					"ICON_URI=\"[^\"]*\"").ToString();
                iconUrl = Regex.Replace(iconUrl, 
					"ICON_URI|\"|=", "");
                //bookmark's icon extracting
                icon = Regex.Match(list[i].Trim(), 
					"ICON=\"[^\"]*\"").ToString();
                icon = Regex.Replace(icon, 
					"\"|ICON|=", "");
                //bookmark's description extracting
                desc = Regex.Match(list[i].Trim(), 
					"DESC=\"[^\"]*\"").ToString();
                desc = Regex.Replace(desc, "DESC|\"|=", "");
                //bookmark's SHORTCUTURL extracting
                keyWords = Regex.Match(list[i].Trim(), 
					"SHORTCUTURL=\"[^\"]*\"").ToString();
                keyWords = Regex.Replace(keyWords, 
					"SHORTCUTURL|\"|=", "");
                //ADD_DATE
                addDate = Regex.Match(list[i].Trim(), 
					"ADD_DATE=\"[^\"]*\"").ToString();
                addDate = Regex.Replace(addDate, "ADD_DATE|\"|=", "");
                //LAST_MODIFIED
                lastModified = Regex.Match(list[i].Trim(), 
					"LAST_MODIFIED=\"[^\"]*\"").ToString();
                lastModified = Regex.Replace(lastModified, 
					"LAST_MODIFIED|\"|=", "");
                //\\
                /////////////////////////////////////////////////////////////
                //write above data in XML file
                Writer.WriteStartElement("BOOKMARK" + i.ToString());
                Writer.WriteAttributeString("NAME", name.Trim());
                Writer.WriteAttributeString("HREF", href.Trim());
                Writer.WriteAttributeString("SHORTCUTURL", keyWords.Trim());
                Writer.WriteAttributeString("DESC", desc.Trim());
                Writer.WriteAttributeString("ADD_DATE", addDate.Trim());
                Writer.WriteAttributeString("LAST_MODIFIED", lastModified.Trim());
                Writer.WriteAttributeString("ICON_URI", iconUrl.Trim());
                Writer.WriteAttributeString("ICON", icon.Trim());
                Writer.WriteEndElement();
            }
        }
        //Writing close tag for the root element.
        Writer.WriteEndDocument();
        Writer.Flush();
        Writer.Close();
        X_Element = XElement.Load(temporaryFileName);
    }
    catch (Exception ex)
    {
        StackFrame file_info = new StackFrame(true);
        error(ref file_info, ex.Message);
    }
}

XML File to TreeView

After creating the XML file, an XML file should be loaded in the TreeView control. (see below methods) If you check Load Icons in settings each icon of nodes will show.

/// 
/// Converts XML file to treeView
/// 
private void XmlToTree()
{
    optimize_menuItem.Enabled = exportIE_favorites.Enabled = 
			exportXML_menuItem.Enabled =
                            exportHtml_menuItem.Enabled = true;
    this.treeViewBookMark.Enabled = true;
    this.XElementClopboard = null;
    this.TreeNodeClipboard = null;

    try
    {
        // SECTION 1. Create a DOM Document and load the XML data into it.
        XmlDocument dom = new XmlDocument();
        dom.Load(this.temporaryFileName);

        // SECTION 2. Initialize the TreeView control.
        treeViewBookMark.Nodes.Clear();
        treeViewBookMark.Nodes.Add(new TreeNode(dom.DocumentElement.Name));
        TreeNode tNode = new TreeNode(rootNodeName);
        tNode = treeViewBookMark.Nodes[0];
        tNode.Name = rootNodeName;

        // SECTION 3. Populate the TreeView with the DOM nodes.
        AddNode(dom.DocumentElement, tNode);

        treeViewBookMark.SelectedNode = treeViewBookMark.Nodes[0];
        selected_node = treeViewBookMark.Nodes[0];
        treeViewBookMark.SelectedNode.Expand();
    }
    catch (Exception ex)
    {
        textBoxIconURL.Enabled = textBoxDesc.Enabled = textBoxName.Enabled 
			= buttonDelIcon.Enabled = textBoxKeyWords.Enabled 
			= textBoxHref.Enabled = false;
        optimize_menuItem.Enabled = exportIE_favorites.Enabled 
			= exportXML_menuItem.Enabled = exportHtml_menuItem.Enabled
                           = false;
        this.treeViewBookMark.Enabled = false;

        StackFrame file_info = new StackFrame(true);
        error(ref file_info, ex.Message);
        return;
    }
}

/// 
/// Creates treeView
/// References : 
/// ms-help://MS.MSDNQTR.v90.en/enu_kbnetframeworkkb/netframeworkkb/317597.htm
/// http://support.microsoft.com/kb/317597
/// 
private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
    try
    {
        XmlNode xNode;
        TreeNode tNode;
        XmlNodeList nodeList;
        int i;
        int j = -1;

        // Loop through the XML nodes until the leaf is reached.
        // Add the nodes to the TreeView during the looping process.
        if (inXmlNode.HasChildNodes)
        {
            nodeList = inXmlNode.ChildNodes;
            for (i = 0; i <= nodeList.Count - 1; i++) 
            {
                if (inXmlNode.ChildNodes[i].Name.Equals("HR"))
                    continue;
                j++;

                xNode = inXmlNode.ChildNodes[i];
                TreeNode newTreeNode;
                newTreeNode = new TreeNode(xNode.Attributes["NAME"].Value);
                newTreeNode.Name = xNode.Name;
                //تعیین عکس هر گره
                //assigns icon of each node -> this code needs more process
                if (loadIcons_menuItem.Checked)
                {
                    Image icon = createIcon(xNode.Name);
                    if (Regex.IsMatch(inXmlNode.ChildNodes[i].Name, "NODE"))
                    {
                        newTreeNode.ImageIndex = 0;
                        newTreeNode.SelectedImageIndex = 0;
                    }
                    else if (icon != null && Regex.IsMatch(inXmlNode.ChildNodes[i].Name,
                        "BOOKMARK"))
                    {
                        imageList1.Images.Add(icon);
                        newTreeNode.ImageIndex = imageList1.Images.Count - 1;
                        newTreeNode.SelectedImageIndex = imageList1.Images.Count - 1;
                    }
                    else
                    {
                        newTreeNode.ImageIndex = 1;
                        newTreeNode.SelectedImageIndex = 1;
                    }
                }
                else
                {
                    if (Regex.IsMatch(inXmlNode.ChildNodes[i].Name, "NODE"))
                    {
                        newTreeNode.ImageIndex = 0;
                        newTreeNode.SelectedImageIndex = 0;
                    }
                    else if (Regex.IsMatch(inXmlNode.ChildNodes[i].Name, "BOOKMARK"))
                    {
                        newTreeNode.ImageIndex = 1;
                        newTreeNode.SelectedImageIndex = 1;
                    }
                }
                //\\
                inTreeNode.Nodes.Add(newTreeNode);
                tNode = inTreeNode.Nodes[j];
                AddNode(xNode, tNode);
            }
        }
        else
        {
            // Here you need to pull the data from the XmlNode based on the
            // type of node, whether attribute values are required, and so forth.
            inTreeNode.Text = (inXmlNode.Attributes["NAME"].Value).Trim();
        }
    }
    catch (Exception ex)
    {
        textBoxIconURL.Enabled = textBoxDesc.Enabled = 
				textBoxName.Enabled = buttonDelIcon.Enabled = 
				textBoxKeyWords.Enabled = textBoxHref.Enabled =
                                     false;
        optimize_menuItem.Enabled = exportIE_favorites.Enabled = 
				exportXML_menuItem.Enabled =
                                     exportHtml_menuItem.Enabled = false;
        treeViewBookMark.Nodes.Clear();
        this.treeViewBookMark.Enabled = false;

        StackFrame file_info = new StackFrame(true);
        error(ref file_info, ex.Message);
        return;
    }
}

KingMark Features

TreeView Drag-n-Drop

You can export IE favorite files directly, using the Drag a TreeView folder or file out to the Window.

Unlike the above, you can import IE favorite files to KingMark with drag it into the TreeView.

Also, you can import IE6 (I had IE6, maybe on IE7 or IE8 doesn't work) website addresses and FF3 (I had FF3, maybe on FF2 or FF1 doesn't work) website tabs into KingMark with dragging it in its TreeView Control.

  

Exporting Bookmarks for Internet Explorer or Firefox Browser

With KingMark you can export all or part of bookmarks for FF(HTML file) or IE(*.url file)

For exporting all bookmarks use the Export Menu:

For exporting some bookmarks use TreeView's contextMenuStrip:

Export for FF
Export for IE

Quick Search


Searching Firefox bookmark manager

I used LINQ to search the XML file (see below method)

private void textBoxSearchTxt_TextChanged(object sender, EventArgs e)
{
    string searchTxt = Regex.Replace(textBoxSearchTxt.Text.Trim(),
        @"[\$\^\{\[\(\|\)\*\+\?\\]", "");
    if (searchTxt == "")
    {
        this.listView1.Items.Clear();
        return;
    }
    try
    {
        var searchNodes = from nodes in X_Element.Descendants()
                          where
                          (nodes.Attribute("NAME") != null    
                          Regex.IsMatch(nodes.Attribute("NAME").Value, 
                          	searchTxt, RegexOptions.IgnoreCase))
                           || (nodes.Attribute("HREF") != null    
                           Regex.IsMatch(nodes.Attribute("HREF").Value, searchTxt, 
                          	 RegexOptions.IgnoreCase))
                           || (nodes.Attribute("SHORTCUTURL") != null    
                           Regex.IsMatch(nodes.Attribute("SHORTCUTURL").Value,
                               searchTxt, 
                           	RegexOptions.IgnoreCase))
                          select nodes;

        listView1.Items.Clear();

        foreach (var node in searchNodes)
        {
            try
            {
                ListViewItem item = new ListViewItem(new string[] 
                { node.Attribute("NAME").Value, node.Attribute("HREF").Value });
                item.Name = node.Name.ToString();
                listView1.Items.Add(item);
            }
            catch
            {
                continue;
            }
        }
    }
    catch { }
}

Generating Website Preview Image

You can find WebsiteThumbnailImage.cs in my project and figure out how I did it.
Firefox bookmark manager

Notify Icon

When you minimize the KingMark window, KingMark creates a contextMenuStrip with the TreeView nodes and show a notifyIcon here:

And you can access to your bookmarks easily:

How can we convert TreeView to contextMenuStrip:

I wrote these methods to do that, and these method did it well. But if you have a better way I thank you if you say it to me.

void createContextMenuStripNotifyIcon()
{
    try
    {
        if (this.treeViewBookMark.Nodes.Count <= 0) return;
        contextMenuStripNotifyIcon.Items.Clear();
        foreach (TreeNode node in this.treeViewBookMark.Nodes[0].Nodes)
        {
            ToolStripMenuItem toolStripMenuItem = new ToolStripMenuItem();
            if (node.GetNodeCount(true) > 0)
            {
                toolStripMenuItem.BackColor = contextMenuStripNotifyIcon.BackColor;
                toolStripMenuItem.Image = imageList1.Images[node.ImageIndex];
                toolStripMenuItem.Text = node.Text.Length > 30 ? 
                	node.Text.Substring(0, 30) + " ..." : node.Text;
                toolStripMenuItem.Name = node.Name;
                createContextMenuStripNotifyIcon(node, ref toolStripMenuItem);
                contextMenuStripNotifyIcon.Items.Add(toolStripMenuItem);
            }
            else
            {
                toolStripMenuItem.BackColor = contextMenuStripNotifyIcon.BackColor;
                toolStripMenuItem.Image = imageList1.Images[node.ImageIndex];
                toolStripMenuItem.Text = node.Text.Length > 30 ? 
                	node.Text.Substring(0, 30) + " ..." : node.Text;
                toolStripMenuItem.Name = node.Name;
                toolStripMenuItem.MouseDown += 
                	new MouseEventHandler(contextMenuStripNotifyIconItems_MouseDown);
                contextMenuStripNotifyIcon.Items.Add(toolStripMenuItem);
            }
        }
    }
    catch (Exception ex)
    {
        StackFrame file_info = new StackFrame(true);
        error(ref file_info, ex.Message);
    }
}

void createContextMenuStripNotifyIcon(TreeNode nodes,
    ref ToolStripMenuItem toolStripMenuItem)
{
    foreach (TreeNode node in nodes.Nodes)
    {
        if (node.GetNodeCount(true) > 0)
        {
            ToolStripMenuItem newToolStripMenuItem = new ToolStripMenuItem();
            newToolStripMenuItem.BackgroundImage = imageList1.Images[node.ImageIndex];
            newToolStripMenuItem.BackgroundImageLayout = ImageLayout.None;
            newToolStripMenuItem.Text = node.Text.Length > 30 ? 
            	node.Text.Substring(0, 30) + " ..." : node.Text;
            newToolStripMenuItem.Name = node.Name;
            createContextMenuStripNotifyIcon(node, ref newToolStripMenuItem);
            toolStripMenuItem.DropDown.Items.Add(newToolStripMenuItem);
        }
        else
        {
            ToolStripMenuItem newToolStripMenuItem = new ToolStripMenuItem();
            newToolStripMenuItem.BackgroundImage = imageList1.Images[node.ImageIndex];
            newToolStripMenuItem.BackgroundImageLayout = ImageLayout.None;
            newToolStripMenuItem.Text = node.Text.Length > 30 ? 
            	node.Text.Substring(0, 30) + " ..." : node.Text;
            newToolStripMenuItem.Name = node.Name;
            newToolStripMenuItem.MouseDown += 
            	new MouseEventHandler(contextMenuStripNotifyIconItems_MouseDown);
            toolStripMenuItem.DropDown.Items.Add(newToolStripMenuItem);
        }
    }
}

void contextMenuStripNotifyIconItems_MouseDown(object sender, MouseEventArgs e)
{
    try
    {
        if (e.Button == MouseButtons.Left)
            Process.Start(GetHref(((ToolStripMenuItem)sender).Name));
    }
    catch
    {
        StackFrame file_info = new StackFrame(true);
        error(ref file_info, "Invalid URL");
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mohammad Dayyan
Iran (Islamic Republic of) Iran (Islamic Republic of)
No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
GeneralMy vote of 5 Pin
hajivalie30-Sep-12 20:11
memberhajivalie30-Sep-12 20:11 
General"=" removed in URL, convert to %3D Pin
kelul22-Nov-10 4:02
memberkelul22-Nov-10 4:02 
GeneralI would venture and say... Pin
pitrovich7-Jan-09 0:06
memberpitrovich7-Jan-09 0:06 
GeneralImport Exported Favorites to IE Pin
AlexandreN12-Oct-08 7:52
memberAlexandreN12-Oct-08 7:52 
GeneralCode for reading the Firefox Bookmark file Pin
Ghostpacket10-Sep-08 20:43
memberGhostpacket10-Sep-08 20:43 
GeneralRe: Code for reading the Firefox Bookmark file Pin
Mohammad Dayyan11-Sep-08 3:15
memberMohammad Dayyan11-Sep-08 3:15 
QuestionWhere can we find FF bookmarks ? Pin
Member 234034-Sep-08 1:01
memberMember 234034-Sep-08 1:01 
AnswerRe: Where can we find FF bookmarks ? Pin
Mohammad Dayyan4-Sep-08 3:54
memberMohammad Dayyan4-Sep-08 3:54 
GeneralUnhandled Exception Pin
hasantayyar2-Sep-08 22:33
memberhasantayyar2-Sep-08 22:33 
GeneralRe: Unhandled Exception Pin
Mohammad Dayyan3-Sep-08 0:13
memberMohammad Dayyan3-Sep-08 0:13 
GeneralRe: Unhandled Exception Pin
hasantayyar3-Sep-08 0:39
memberhasantayyar3-Sep-08 0:39 
GeneralRe: Unhandled Exception Pin
Mohammad Dayyan3-Sep-08 0:55
memberMohammad Dayyan3-Sep-08 0:55 
GeneralDateTime question Pin
Member 451037225-Aug-08 10:53
memberMember 451037225-Aug-08 10:53 
GeneralRe: DateTime question Pin
Mohammad Dayyan26-Aug-08 11:09
memberMohammad Dayyan26-Aug-08 11:09 
GeneralRe: DateTime question Pin
Member 451037229-Aug-08 4:51
memberMember 451037229-Aug-08 4:51 
GeneralRe: DateTime question Pin
Mohammad Dayyan29-Aug-08 10:28
memberMohammad Dayyan29-Aug-08 10:28 
GeneralThis is shorter Pin
Vasian Cepa21-Sep-08 23:47
memberVasian Cepa21-Sep-08 23:47 
GeneralRe: This is shorter Pin
Mohammad Dayyan22-Sep-08 3:34
memberMohammad Dayyan22-Sep-08 3:34 
QuestionFF V3? Pin
Metal-Frog6-Aug-08 20:15
memberMetal-Frog6-Aug-08 20:15 
AnswerRe: FF V3? Pin
Mohammad Dayyan7-Aug-08 2:44
memberMohammad Dayyan7-Aug-08 2:44 
GeneralRe: FF V3? Pin
Metal-Frog7-Aug-08 19:46
memberMetal-Frog7-Aug-08 19:46 
GeneralRe: FF V3? Pin
Mohammad Dayyan8-Aug-08 1:12
memberMohammad Dayyan8-Aug-08 1:12 
GeneralRe: FF V3? Pin
Metal-Frog8-Aug-08 1:33
memberMetal-Frog8-Aug-08 1:33 
GeneralRe: FF V3? Pin
Mohammad Dayyan8-Aug-08 7:32
memberMohammad Dayyan8-Aug-08 7:32 
AnswerRe: FF V3? Pin
Shawn Horton8-Aug-08 5:50
memberShawn Horton8-Aug-08 5:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170915.1 | Last Updated 24 Sep 2008
Article Copyright 2008 by Mohammad Dayyan
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid