C# 記一次對chm幫助文檔的信息提取

事情時這樣,有用友u8的字典數據的幫助文檔一份,同事須要把裏面的不少張表的字典信息給提取出來,而後構成sql語句,插入數據庫。字典就是一張對錶裏的字段的一個說明,長這樣
同事一開始是手動複製到excel文檔在改的,他問我有沒有什麼簡單的辦法,因此我就決定用代碼去實現,把表格、表名等一些有效數據構成對象,有了一個對象就好寫sql了。
 
首先,我在百度上搜索,發現這個chm幫助文檔能被反編譯成html,通過一番操做,使用windows自帶的工具 hh.exe 就能夠實現幫助文檔的反編譯。運行cmd,直接輸入命令就行,具體命令是這樣:
 
hh -decompile d:\test\help help.chm
 
d:\test\help是反編譯後的目錄。
 
反編譯以後,就會獲得具體的html文檔,和js、css,長這樣:
test目錄是我本身建的。
 
後面就是查看html源碼,分析出關鍵信息的xPath路徑該怎麼寫,由於這裏我用到了.net的一款工具專門對html操做的,叫作:HtmlAgilityPack,個人翻譯是:html敏捷開發包,寫xpath比寫正則來的容易,這個包能很好的操做html的節點,獲取html、innertext、屬性。
 
貼上個人關鍵方法:
public TableInfo GetTableInfo()
        {
            TableInfo tab = new TableInfo();
            HtmlDocument doc = new HtmlDocument();
            doc.Load(FullPathName, Encoding.GetEncoding("gb2312"), true);
           
            if (doc == null)
            {
                throw  new NullReferenceException(FullPathName + "\r\n沒有加載出文檔");
            }
            string pathGetTableName = "/html/head/title";
            string pathGetTableDesc = "/div/p";
            String pathGetTd = "/div/table/tr";
            var nodeTitle=doc.DocumentNode.SelectSingleNode(pathGetTableName);
            if (null != nodeTitle)
            {
                tab.TableName = nodeTitle.InnerText.Split(new char[1] { ' '})[0].Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("&", "").Replace("nbsp;", "");

            }

            var nodeBody = doc.GetElementbyId("pagebody");
            var str = nodeBody.OuterHtml;
            var doc1 = new HtmlDocument();
            doc1.LoadHtml(str);
            var nodeDesc = doc1.DocumentNode.SelectSingleNode(pathGetTableDesc);
            if (null != nodeDesc)
            {
                tab.tableDescription = nodeDesc.InnerText.Split(new char[1] { ' ' })[0].Replace("\r","").Replace("\n", "").Replace("\t", "").Replace("&", "").Replace("nbsp;", "");

            }
           
            var nodesTr = doc1.DocumentNode.SelectNodes(pathGetTd);
            if (nodesTr == null)
            {
                return tab;
            }

            List<TabFieldInfo> lists = new List<TabFieldInfo>();

            for (var i = 1; i < nodesTr.Count(); i++)
            {
                var childs = nodesTr[i].ChildNodes;

                if (childs == null)
                {
                    continue;
                }
                TabFieldInfo fi = new TabFieldInfo();
                if (childs.Count <= 5)
                {
                    continue;
                }
                fi.ColumnName = childs[1].ChildNodes[1].InnerText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("&", "").Replace("nbsp;", "");
                fi.Description = childs[2].InnerText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("&", "").Replace("nbsp;", "");
                fi.Datatype = childs[3].InnerText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("&", "").Replace("nbsp;", "");
                fi.Length = childs[4].InnerText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("&", "").Replace("nbsp;", "");
                fi.AllowNulls = childs[5].InnerText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("&", "").Replace("nbsp;", "");

                lists.Add(fi);
            }
            tab.fields = lists;

            return tab;
        }
這裏還出現一個問題,「指定的路徑不合法」,緣由是,我直接點擊文件右鍵-》屬性-》安全 把那裏的文件路經複製到代碼上去了,其實這樣複製,會形成路徑字符串最開始的地方有個特殊字符,在vs裏是隱藏的,後來我就複製地址欄上的路徑,就沒問題了。
 
最後,須要完善的是,經過讀取目錄,把目錄中的全部html結尾的文件遍歷,並過濾出須要的表,在構建對象。
相關文章
相關標籤/搜索