• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Codejie's C++ Space

            Using C++

            輪子:用于分析Lingoes結果的HTML解析對象(二)


                今天才有時間繼續寫HTML解析對象的查找部分代碼。代碼如下,下次再整理~

                CDocumentObject類,增加了兩類查詢函數,一種用于從根部開始的遍歷性查詢,另一種則是指定Tag范圍內查詢。
            class CDocumentObject
            {
            protected:
                static const char TAG_LT        =   '<';
                static const char TAG_GT        =   '>';
                static const char TAG_SLASH     =   '/';
                static const char TAG_BSLASH    =   '\\';
                static const char TAG_AND       =   '&';

                typedef std::vector<CParserData> TDataVector;

                typedef std::stack<CParserData> TDataStack;
                struct TNodeData
                {
                    size_t level;
                    CParserData tag;
                    CParserData value;
            //        CParserData end;
                };
                typedef std::deque<TNodeData> TNodeQueue;
            public:
                typedef std::stack<const CElementObject*> TElementStack;
            public:
                CDocumentObject();
                virtual ~CDocumentObject();

                int Load(const std::string& str);

                const CElementObject* Root() const;

                const CElementObject* FindFirstElement(const std::string& tag);
                const CElementObject* FindNextElement();

                const CElementObject* FindFirstElement(const CElementObject* element, const std::string& tag, TElementStack& tmpstack);
                const CElementObject* FindNextElement(const CElementObject* element, const std::string& tag, TElementStack& tmpstack);

                const CAttributeObject* FindAttribute(const CElementObject* element, const std::string& attr);
                
                void Show(std::ostream& os) const;
            protected:
                int PreProcess(const std::string& str, std::string& html);
                int PreParser(const std::string& html, TNodeQueue& vct);
                int Parser(const std::string& html, TNodeQueue& que);
            private:
                int PreParserLT(const std::string& html, std::string::size_type& pos, CParserData& data);
                int PushValueData(const CParserData& data, TDataStack& datastack) const;
                int PushTagData(const std::string& html, const CParserData& data, TDataStack& datatstack, TNodeQueue& nodeque) const;
                
                int CheckSpecialTag(const std::string& html, const CParserData& data) const;
                int CheckTag(const std::string& html, const CParserData& tag, const CParserData& end) const;
                CElementObject* MakeElement(const std::string& html, const TNodeData& node, CElementObject* parent, CElementObject* sibling) const;

                void CDocumentObject::ShowElement(std::ostream& os, const CElementObject* e) const;

                void FreeElement(CElementObject* root);

                const CElementObject* FindElement(const CElementObject* root, const CElementObject* pe, const std::string& tag, TElementStack& stack);
            private:
                CElementObject* _root;
            private:
                std::string _findtag;
                TElementStack _findstack;
            };

                實現代碼如下:
            const CElementObject* CDocumentObject::FindFirstElement(const std::string &tag)
            {
                
            if(_root == NULL)
                    
            return NULL;

                _findtag 
            = tag;
                
            while(!_findstack.empty())
                    _findstack.pop();
             
                
            return FindElement(NULL, _root, _findtag, _findstack);
            }


            const CElementObject* CDocumentObject::FindNextElement()
            {
                
            if(_findstack.empty())
                    
            return NULL;

                
            return FindElement(NULL, _findstack.top()->child, _findtag, _findstack);
            }


            const CElementObject* CDocumentObject::FindFirstElement(const CElementObject* element, const std::string& tag, TElementStack& tmpstack)
            {
                
            if(element == NULL)
                    
            return NULL;

                
            while(!tmpstack.empty())
                    tmpstack.pop();

                
            return FindElement(element, element, tag, tmpstack);
            }


            const CElementObject* CDocumentObject::FindNextElement(const CElementObject* element, const std::string& tag, TElementStack& tmpstack)
            {
                
            if(tmpstack.empty())
                    
            return NULL;

                
            return FindElement(element, tmpstack.top()->child, tag, tmpstack);
            }


            const CElementObject* CDocumentObject::FindElement(const CElementObject* root, const CElementObject* pe, const std::string& tag, TElementStack& stack)
            {
                
            while(pe != NULL)
                
            {
                    stack.push(pe);
                    
            if(pe->tag == tag)
                        
            return pe;
                    pe 
            = pe->child;
                }

                
                
            while(!stack.empty() && stack.top() != root && pe == NULL)
                
            {
                    pe 
            = stack.top()->sibling;  
                    stack.pop();
                }


                
            if(pe == NULL)
                    
            return NULL;

                
            return FindElement(root, pe, tag, stack);
            }


            const CAttributeObject* CDocumentObject::FindAttribute(const TinyHtmlParser::CElementObject *element, const std::string &attr)
            {
                
            if(element == NULL)
                    
            return NULL;
                
                
            const CAttributeObject* pa = element->attrib;
                
            while(pa != NULL)
                
            {
                    
            if(pa->attr == attr)
                        
            return pa;
                    pa 
            = pa->next;
                }

                
            return pa;
            }


                先不關心性能和繁瑣性,能寫成這樣已經累的我半死了。。。通過寫這個功能,發現自己對于算法的設計不能一步到位,實現過程中總是有這樣或哪樣的地方沒有考慮到,整個對象簡直就是測試出來的。。。還好一條路不通,能馬上換一條,還好敲字快,能馬上再敲一邊。。。

                下面是測試代碼:

                const CElementObject* pe = doc.FindFirstElement("TABLE");
                
                
            while(pe != NULL)
                
            {
                    pe
            ->Show(std::cout);

                    CDocumentObject::TElementStack tmp;

                    
            const CElementObject* p = doc.FindFirstElement(pe, "DIV", tmp);
                    
            while(p != NULL)
                    
            {
                        p
            ->Show(std::cout);
                        p 
            = doc.FindNextElement(pe, "DIV", tmp);
                    }

                    pe 
            = doc.FindNextElement();
                }


            --------------------

            [
            3]Tag : TABLE
                attr : onselectstart 
            -- value = "return true"
                attr : id 
            -- value = dict_head_E1C27E806399D047822B6650194A3D32
                attr : cellSpacing 
            -- value = 0
                attr : cellPadding 
            -- value = 0
                attr : border 
            -- value = 0

            [
            7]Tag : DIV
                attr : onmouseup 
            -- value = "this.className='btn2_mouse_up'"
                attr : 
            class -- value = btn2_mouse_out
                attr : onmousedown 
            -- value = "this.className='btn2_mouse_down'"
                attr : id 
            -- value = dict_title_E1C27E806399D047822B6650194A3D32
                attr : onmouseover 
            -- value = "this.className='btn2_mouse_over'"
                attr : title 
            -- value = "Dictionary Menu"
                attr : style 
            -- value = "MARGIN: 0px 3px 1px 0px"
                attr : onclick 
            -- value = "window.navigate('app://dictmenu/E1C27E806399D047822B6650194A3D32-2')"
                attr : onmouseout -- value = "this.className='btn2_mouse_out'"

            [
            7]Tag : DIV
                attr : style 
            -- value = "OVERFLOW: hidden; WIDTH: 10px; CURSOR: hand; MARGIN-RIGHT: 2px; HEIGHT: 10px"

            posted on 2010-02-22 18:32 codejie 閱讀(268) 評論(0)  編輯 收藏 引用 所屬分類: C++輪子精神

            公告

            Using C++

            導航

            統計

            留言簿(73)

            隨筆分類(513)

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            久久中文字幕人妻熟av女| 久久久久久免费一区二区三区| 久久天堂电影网| 久久福利片| 国产精品久久久久久久久免费| 久久免费看黄a级毛片| 久久久精品国产亚洲成人满18免费网站| 久久综合鬼色88久久精品综合自在自线噜噜 | 亚洲狠狠婷婷综合久久蜜芽| 久久电影网一区| 久久99国产综合精品| 久久久一本精品99久久精品88 | 久久久久波多野结衣高潮| 色欲久久久天天天综合网精品| 久久综合九色综合97_久久久| 久久久久久青草大香综合精品| 欧美午夜精品久久久久免费视 | 久久亚洲熟女cc98cm| 国产精品VIDEOSSEX久久发布| 久久国产免费观看精品| 国产亚洲精久久久久久无码77777| 久久经典免费视频| 99久久综合国产精品二区| 狠狠色丁香久久婷婷综合五月 | 久久精品国产亚洲AV嫖农村妇女| 久久久久久国产精品美女| 欧美亚洲国产精品久久蜜芽| 国内精品久久久久久久97牛牛| 一本一本久久a久久综合精品蜜桃| 久久AⅤ人妻少妇嫩草影院| 国产精品久久久久久久午夜片 | 亚洲精品高清国产一久久| 欧美日韩中文字幕久久伊人| 久久男人Av资源网站无码软件| 日韩精品久久久肉伦网站| 人妻无码久久一区二区三区免费| 久久热这里只有精品在线观看| 狠狠色丁香婷婷久久综合| 久久人人爽人人爽人人av东京热| 人人妻久久人人澡人人爽人人精品 | 精品久久久久一区二区三区|