• <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免费看| 狠狠久久亚洲欧美专区| 亚洲精品蜜桃久久久久久| 久久精品人人做人人爽电影蜜月| 精品久久久久久久久久久久久久久 | 色成年激情久久综合| 久久毛片一区二区| 99久久国产免费福利| 久久亚洲AV无码精品色午夜 | 国产成人99久久亚洲综合精品 | 久久综合九色综合精品| 久久久久久伊人高潮影院| 狠狠狠色丁香婷婷综合久久俺| 亚洲精品成人网久久久久久| 久久香蕉超碰97国产精品| 久久综合日本熟妇| 国产A级毛片久久久精品毛片| 国产精品久久久久AV福利动漫| 伊人久久大香线蕉精品不卡 | 国产A级毛片久久久精品毛片| 狠狠色伊人久久精品综合网| 人妻无码久久一区二区三区免费| 中文精品久久久久人妻| 一级做a爰片久久毛片16| 久久久久亚洲精品无码蜜桃 | 久久精品中文字幕有码| 亚洲国产二区三区久久| 久久电影网2021| 久久91精品国产91久久户| 久久精品www人人爽人人| 国内精品久久久久久99蜜桃 | 奇米影视7777久久精品人人爽| 久久久久久久国产免费看| 久久精品国产亚洲精品| 色诱久久av| 久久乐国产精品亚洲综合| 国产精品免费看久久久香蕉| 99久久精品国产毛片| 日本久久久精品中文字幕| 人人狠狠综合久久亚洲婷婷| 情人伊人久久综合亚洲|