65.9K
CodeProject 正在变化。 阅读更多。
Home

合并 Firefox json 书签

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (3投票s)

2012年6月17日

CPOL
viewsIcon

31266

downloadIcon

471

一个实用工具,用于合并两个 Firefox JSON 书签文件,同时保留标签和目录结构。

介绍 

如果你想合并两台机器(例如,工作和家庭)的书签,Firefox 不允许你合并书签,它只允许你替换当前的书签。

背景  

这段代码使用 Jayrock JSON 库来操作 JSON 文本。

http://jayrock.berlios.de

使用代码

Firefox 书签文件主要由 4 个数组组成:标签、书签菜单、书签工具栏和未排序的书签。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jayrock.Json.Conversion;
using System.Collections;
using System.Windows.Forms;

namespace mergeBookmarks
{
    static class Merge
    {
        static int maxId = 0;
        static IDictionary findItem(string menu, string sUri,  Jayrock.Json.JsonArray jArray)
        {
            IDictionary foundNode = null;
            int i;
            for (i = 0; i < jArray.Count(); i++)
            {

                if (jArray[i].GetType() == typeof(Jayrock.Json.JsonObject))
                {
                    IDictionary node =(IDictionary) jArray[i];
                    if (node.Contains("title"))
                    {
                        if ((node["title"] == null && menu == null) || Convert.ToString(node["title"]).Equals(menu))
                        {
                            foundNode = (IDictionary)jArray[i];
                            if (node.Contains("uri"))
                            {
                                if (Convert.ToString(node["uri"]).Equals(sUri))
                                {
                                    return foundNode;
                                }
                            }
                            else
                            {
                                return foundNode;
                            }
                        }
                    }
                }
                else if (jArray[i].GetType() == typeof(Jayrock.Json.JsonArray))
                {
                }
                else
                {
                }
            }
            return foundNode;

        }
        static int findMaxIndex(Jayrock.Json.JsonArray jArray)
        {
            int index = 0;
            int i;
            for (i = 0; i < jArray.Count(); i++)
            {
                if (jArray[i].GetType() == typeof(Jayrock.Json.JsonObject))
                {
                     IDictionary node =(IDictionary)jArray[i];
                    if (node.Contains("index"))
                    {
                        if (Convert.ToInt32(node["index"])>index)
                            index = Convert.ToInt32(node["index"]);
                    }
                }
                else
                {
                }
            }
            return index;
        }
        static void adjustIds( int parent, Jayrock.Json.JsonArray jArray)
        {
            IEnumerator<object> jTagEnum = jArray.GetEnumerator();
            int index = 0;
            while (jTagEnum.MoveNext())
            {
                IDictionary obj= (IDictionary)jTagEnum.Current;
                obj["id"] = maxId++;
                obj["parent"] = parent;
                if (!obj.Contains("index"))
                {
                    if (index > 0)
                        obj.Add("index", index);
                }
                else
                {
                    obj["index"] = index;
                }
                index++;
                if (obj["type"].ToString().Equals("text/x-moz-place-container"))
                {
                    adjustIds(Convert.ToInt32(obj["id"]), (Jayrock.Json.JsonArray)obj["children"]);
                }
            }
        }

        static void doMergeLists(IDictionary node1, IDictionary node2)
        {
            string sType1, sType2;
            sType1 = node1["type"].ToString();
            sType2 = node2["type"].ToString();
            if (!sType1.Equals("text/x-moz-place-container") || !sType2.Equals("text/x-moz-place-container"))
            {
                throw new Exception("not container");
            }

            Jayrock.Json.JsonArray jArray1 = (Jayrock.Json.JsonArray)node1["children"];
            int TagsId = Convert.ToInt32(node1["id"]);
            Jayrock.Json.JsonArray jArray2 = (Jayrock.Json.JsonArray)node2["children"];
            int maxTagsIndex = findMaxIndex(jArray1) + 1;
            IEnumerator<object> jArray2Enum = jArray2.GetEnumerator();
            while (jArray2Enum.MoveNext())
            {
                IDictionary node = (IDictionary)jArray2Enum.Current;
                if (node.Contains("title"))
                {
                    string title=null;
                    if (node["title"] != null)
                        title = node["title"].ToString();
                    else
                        title = null;
                    string sItemType2 = node["type"].ToString();
                    if ((title != null && (title.Equals("Recently Bookmarked") || title.Equals("Recent Tags"))) || sItemType2 == "text/x-moz-place-separator")
                    {
                        continue;
                    }
                    IDictionary obj = null;
                    if (node.Contains("uri"))
                    {
                        string sUri = node["uri"].ToString();
                         obj = findItem(title, sUri, jArray1);
                    }
                    else
                    {
                         obj = findItem(title, "", jArray1);
                    }
                    if (obj != null)
                    {
                        string sItemType1 = obj["type"].ToString();
                        if (sItemType1.Equals(sItemType2))
                        {
                            // equal Types, then will do merge
                            if(sItemType1.Equals("text/x-moz-place"))
                            {
                                string sUri = node["uri"].ToString();
                                if (node["uri"].ToString().Equals(obj["uri"].ToString()))
                                {
                                    // equal title and uri, do nothing
                                }
                                else
                                {
                                    // equal title, but different uri, rename node
                                    int i = 1;
                                    IDictionary tObj;
                                    if (title != null)
                                    {
                                        while ((tObj = findItem(title + "(" + i + ")", sUri, jArray1)) != null)
                                        {
                                            i++;
                                        }
                                    }
                                    string obj1Text = node.ToString();
                                    if (!node.Contains("index"))
                                    {
                                        obj1Text = obj1Text.Insert(1, "\"index\":" + maxTagsIndex.ToString() + ",");
                                    }
                                    IDictionary obj1 = (IDictionary)JsonConvert.Import(obj1Text);
                                    int objId = maxId++;
                                    if(title != null)
                                        obj1["title"] = obj1["title"].ToString() + "(" + i + ")";

                                    obj1["id"] = objId;
                                    obj1["parent"] = TagsId;
                                    obj1["index"] = maxTagsIndex++;
                                    if (obj1["type"].ToString().Equals("text/x-moz-place-container"))
                                        adjustIds(objId, (Jayrock.Json.JsonArray)obj1["children"]);
                                    jArray1.Add(obj1);
                                }
                            }
                            else
                            {
                                // merge lists
                                doMergeLists(obj, node);
                            }
                        }
                        else
                        {
                            // types not equal, rename node
                            int i = 1;
                            IDictionary tObj;
                            string sUri1 = null;
                            if(node.Contains("uri"))
                                 sUri1 = node["uri"].ToString();
                            while ((tObj = findItem(title + "(" + i + ")",sUri1, jArray1)) != null)
                            {
                                i++;
                            }
                            string obj1Text = node.ToString();
                            if (!node.Contains("index"))
                            {
                                obj1Text = obj1Text.Insert(1, "\"index\":" + maxTagsIndex.ToString() + ",");
                            }
                            IDictionary obj1 = (IDictionary)JsonConvert.Import(obj1Text);
                            int objId = maxId++;
                            obj1["title"] = obj1["title"].ToString() + "(" + i + ")";
                            obj1["id"] = objId;
                            obj1["parent"] = TagsId;
                            obj1["index"] = maxTagsIndex++;
                            adjustIds(Convert.ToInt32(obj1["id"]), (Jayrock.Json.JsonArray)obj1["children"]);
                            jArray1.Add(obj1);

                        }
                    }
                    else
                    {
                        // not duplicate node
                            string obj1Text = node.ToString();
                            if (!node.Contains("index"))
                            {
                                obj1Text = obj1Text.Insert(1, "\"index\":" + maxTagsIndex.ToString() + ",");
                            }
                            IDictionary obj1 = (IDictionary)JsonConvert.Import(obj1Text);
                            int objId = maxId++;
                            obj1["id"] = objId;
                            obj1["parent"] = TagsId;
                            obj1["index"] = maxTagsIndex++;
                            if(sItemType2.Equals("text/x-moz-place-container"))
                                adjustIds(Convert.ToInt32(obj1["id"]), (Jayrock.Json.JsonArray)obj1["children"]);
                            jArray1.Add(obj1);
                    }
                }
            }
        }

        static int findMaxId( ref int id,Jayrock.Json.JsonArray jArray )
        {
            int i;
            for (i = 0; i < jArray.Count(); i++)
            {
                if (jArray[i].GetType() == typeof(Jayrock.Json.JsonObject))
                {
                    findMaxId(ref id, (IDictionary)jArray[i]);

                }
                else if (jArray[i].GetType() == typeof(Jayrock.Json.JsonArray))
                {
                    findMaxId(ref id, (Jayrock.Json.JsonArray)jArray[i]);
                }
                else
                {
//                    parseItem(jArray[i]);
                    Console.WriteLine(" {0,-25} {1}", ((DictionaryEntry)jArray[i]).Key, ((DictionaryEntry)jArray[i]).Value.GetType().ToString(), ((DictionaryEntry)jArray[i]).Value.ToString());
                }
            }
            return id;
        }
        static int findMaxId(ref int id, IDictionary node)
        {
            
            if(node.Contains("id")){
                if(Convert.ToInt32( node["id"]) > id)
                    id=Convert.ToInt32(node["id"]);
            }
            IDictionaryEnumerator dict = node.GetEnumerator();
            while (dict.MoveNext())
            {
                if (dict.Value == null)
                {
                }
                else if (dict.Value.GetType() == typeof(Jayrock.Json.JsonArray))
                {
                    findMaxId(ref id, (Jayrock.Json.JsonArray)dict.Value);
                }
                else if (dict.Value.GetType() == typeof(Jayrock.Json.JsonObject))
                {
                    findMaxId(ref id, (IDictionary)dict.Value);
                }
            } 

            return id;
        }
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMerge());
        }
        public static void MergeBookmarks(string srcFile1, string srcFile2, string DstFile)
        {
            string jsontext = System.IO.File.ReadAllText(srcFile1);
            IDictionary root1 = (IDictionary)JsonConvert.Import(jsontext);
             jsontext = System.IO.File.ReadAllText(srcFile2);
            IDictionary root2 = (IDictionary)JsonConvert.Import(jsontext);
            int id = 0;
            findMaxId(ref id, root1);
            maxId = id+1;
            doMergeLists(root1, root2);
            System.IO.File.WriteAllText(DstFile, root1.ToString());
        }
    }
}



关注点

Jayrock JSON 库是一个非常优秀且易于使用的工具。

历史

首次发布

© . All rights reserved.