HTML解析-第2版(C/C++)


  :
          ,    HTML      “URL” “  ”,            。
  :
  “  ”  ,                 ,            ,
        “  ”  “  ” 。  “URL”   ,  “  ”    ,
      “  ‘  ’  ”。        ,      ,  ,   ,    。
  :
<a href="http://www.csdn.net" >csdn</a>
<script src="http://csdnimg.cn/xxxxxxxx.js" type="text/javascript"></script>
    “csdn”     ,              3 ,         1 。
  :
<a href="http://bbs.csdn.net" >  </a>
<a href="http://bbs.csdn.net" >   </a>
<a href="http://bbs.csdn.net" >    </a>
    “  ”     ,     ,         3 。
              1 ,      “  ”     ,
                 。

  :
1:         ,       。
2:   MS COM ,       ,          。
3:                ,               。

  :
   HTML                   ,      ,       。

  :
HTML     :<a href="http://www.csdn.net" >aaaa</a>   <link href="/favicon.ico" />
            ,          (          “  ”)。
   (          )    “ <>""''=   ”,                   ,
“  ”a “  ”/a “ ”   “ ”     ,“  ”a “  ”href “  ”     。
          “  ”  ,                 。
      “  ” “  ”,      “  ”   “URL”。
           ,          。 :    ,            ,
           ,       HTML  (             )。

                                                                                                                                                               

//////////////////////////////      2011-12-17  18:01    /////////////////////////////////////////

1:「HTML解析-第1版(C/C++)」よりメモリコピーが少なく、比較的高速化されています.
2:コードはVS 2008でテストに合格しました.#define _UNICODE #define _WIN32_WINNT 0x0600
3:解析方法:mapテーブルの構築(STLテンプレートライブラリのmapは読み取りに不利で、MFCクラスライブラリのCMapを参照することができる)と同様に、最終的に2次元の一方向チェーンテーブルを構成する.
4:CHtmlObjectクラスはHTMLの「タグ」と「属性」を解析します.
//////////////////////////////////////////////////////////////////////////////////////////CHtmlObject.h//////////////////////////////////////////////////////////////////////////

#pragma once

/*****************************************************************************************************************
created: 2011/12/03
author: hmm7e ([email protected])

*****************************************************************************************************************/

class CHtmlObject
{
public:
//
static BOOL IsSpace(TCHAR tcLetter);
protected:
struct tagNode
{
LPCTSTR s_pszKey;
LPCTSTR s_pszValue;
struct tagNode * s_pstRight; //attribute of tag
struct tagNode * s_pstNext; //next tag
};
public:
CHtmlObject(void);
virtual ~CHtmlObject(void);
//
enum {CHARSET_UTF8,CHARSET_UNICODE,CHARSET_MULTIBYTE}TextCharset;
protected:
//
tagNode * InnerAllocNode();
void InnerFreeNode(tagNode * lpstNode);
void InnerLinkNextNode(tagNode * lpstNode);
void InnerLinkRightNode(tagNode * lpstTagNode,tagNode * lpstNode);
void InnerCleanupNode();
void InnerCleanupRightNode(tagNode * lpstNode);
public:
//
void AutoTakeSnapshot(PBYTE lpszString,UINT nStringLen);
void TakeSnapshot(PBYTE lpszString,UINT nStringLen,UINT nFromCharset );
void DeleteSnapshot();
//
void Parse();
private:
//
void InnerParse();
LPTSTR InnerSplitComment(tagNode * lpstNode,LPTSTR lpszTagString);
LPTSTR InnerSplitTag(tagNode * lpstNode,LPTSTR lpszTagString);
LPTSTR InnerSplitContent(tagNode * lpstNode,LPTSTR lpszTagString);
LPTSTR InnerSplitText(tagNode * lpstNode,LPTSTR lpszTagString);
LPTSTR InnerSplitScript(tagNode * lpstNode,LPTSTR lpszTagString);
LPTSTR InnerSplitStyle(tagNode * lpstNode,LPTSTR lpszTagString);

protected:
//
LPTSTR m_pszSnapshotBuffer;
UINT m_nSnapshotBufferLen;
UINT m_nSnapshotStringLen;
//
tagNode * m_pstHead;
tagNode * m_pstTail;

};

//////////////////////////////////////////////////////////////////////////////////////////CHtmlObject.h//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////CHtmlObject.cpp//////////////////////////////////////////////////////////////////////////

#pragma once

/*****************************************************************************************************************
created: 2011/12/03
author: hmm7e ([email protected])

*****************************************************************************************************************/


#include "HtmlObject.h"

//
BOOL CHtmlObject::IsSpace(TCHAR tcLetter)
{
	//     HTML        。
	return (tcLetter == _T(' ') || tcLetter == _T('\r') ||tcLetter == _T('
') ||tcLetter == _T('\t') ); } CHtmlObject::CHtmlObject(void) { m_pszSnapshotBuffer = NULL; m_nSnapshotBufferLen = 0; m_nSnapshotStringLen = 0; m_pstHead = NULL; m_pstTail = NULL; } CHtmlObject::~CHtmlObject(void) { DeleteSnapshot(); } // CHtmlObject::tagNode * CHtmlObject::InnerAllocNode() { CHtmlObject::tagNode * pstResult = new CHtmlObject::tagNode; if( pstResult ) { ::ZeroMemory((LPVOID)pstResult,sizeof(CHtmlObject::tagNode)); } return pstResult; } void CHtmlObject::InnerFreeNode(CHtmlObject::tagNode * lpstNode) { if( lpstNode ) delete lpstNode; } void CHtmlObject::InnerLinkNextNode(tagNode * lpstNode) { // “ ” 。 //1: “ ” , “ ” 。 //2: “ ” , “ ” , “ ” 。 if( m_pstHead == NULL ) { m_pstHead = lpstNode; m_pstTail = lpstNode; } else { m_pstTail->s_pstNext = lpstNode; m_pstTail = lpstNode; } #ifdef _DEBUG if( lpstNode->s_pszKey ) { ::OutputDebugString(_T("--")); ::OutputDebugString(lpstNode->s_pszKey); ::OutputDebugString(_T("--\r
")); } if( lpstNode->s_pszValue ) { ::OutputDebugString(_T("--")); ::OutputDebugString(lpstNode->s_pszValue); ::OutputDebugString(_T("--\r
")); } #endif //_DEBUG } void CHtmlObject::InnerLinkRightNode(tagNode * lpstTagNode,tagNode * lpstNode) { // “ ” “ ” 。 //1: “ ” , 。 //2: “ ” 。 lpstNode->s_pstRight = lpstTagNode->s_pstRight; lpstTagNode->s_pstRight = lpstNode; #ifdef _DEBUG if( lpstNode->s_pszKey ) { ::OutputDebugString(_T("-->")); ::OutputDebugString(lpstNode->s_pszKey); ::OutputDebugString(_T("<--\r
")); } if( lpstNode->s_pszValue ) { ::OutputDebugString(_T("-->")); ::OutputDebugString(lpstNode->s_pszValue); ::OutputDebugString(_T("<--\r
")); } #endif //_DEBUG } void CHtmlObject::InnerCleanupNode() { // 。 “ ” 。 CHtmlObject::tagNode * pstPrev = NULL; while( m_pstHead ) { pstPrev = m_pstHead; m_pstHead = m_pstHead->s_pstNext; //first InnerCleanupRightNode(pstPrev); //second InnerFreeNode(pstPrev); } m_pstHead = NULL; m_pstTail = NULL; } void CHtmlObject::InnerCleanupRightNode(CHtmlObject::tagNode * lpstNode) { // “ ” 。 CHtmlObject::tagNode * pstHead = lpstNode->s_pstRight; CHtmlObject::tagNode * pstPrev = NULL; while( pstHead ) { pstPrev = pstHead; pstHead = pstHead->s_pstRight; InnerFreeNode(pstPrev); } pstHead = NULL; pstPrev = NULL; } // void CHtmlObject::AutoTakeSnapshot(PBYTE lpszString,UINT nStringLen) { if( lpszString && nStringLen > 0) { // 。 if( nStringLen >= 2 ) { if( lpszString[0] == 0xFF && lpszString[1] == 0xFE ) // skip 0xFF,0xFE { TakeSnapshot(lpszString+2,nStringLen-2,CHtmlObject::CHARSET_UNICODE); } else if( lpszString[0] == 0xEF && lpszString[1] == 0xBB && lpszString[2] == 0xBF )// skip 0xEF,0xBB,0xBF { TakeSnapshot(lpszString+3,nStringLen-3,CHtmlObject::CHARSET_UTF8); } else { TakeSnapshot(lpszString,nStringLen,CHtmlObject::CHARSET_MULTIBYTE); } } else { TakeSnapshot(lpszString,nStringLen,CHtmlObject::CHARSET_MULTIBYTE); } } } void CHtmlObject::TakeSnapshot(PBYTE lpszString,UINT nStringLen,UINT nFromCharset ) { //delete old snapshot DeleteSnapshot(); if( lpszString && nStringLen > 0 ) { //transform to TCHAR if( CHtmlHelper::CHARSET_UTF8 == nFromCharset ) { #ifdef _UNICODE m_nSnapshotBufferLen = nStringLen; m_pszSnapshotBuffer = new TCHAR[m_nSnapshotBufferLen]; ::memset((LPVOID)m_pszSnapshotBuffer,0,m_nSnapshotBufferLen*sizeof(TCHAR)); m_nSnapshotStringLen = ::MultiByteToWideChar(CP_UTF8,0,(LPCSTR)lpszString,nStringLen,m_pszSnapshotBuffer,m_nSnapshotBufferLen); #else ::OutputDebugString(_T("no support")); #endif //_UNICODE } else if( CHtmlHelper::CHARSET_UNICODE == nFromCharset ) { #ifdef _UNICODE m_nSnapshotBufferLen = nStringLen; m_pszSnapshotBuffer = new TCHAR[m_nSnapshotBufferLen]; ::memset((LPVOID)m_pszSnapshotBuffer,0,m_nSnapshotBufferLen*sizeof(TCHAR)); ::memcpy((LPVOID)m_pszSnapshotBuffer,lpszString,nStringLen); #else m_nSnapshotBufferLen = nStringLen/2+1; m_pszSnapshotBuffer = new TCHAR[m_nSnapshotBufferLen]; ::memset((LPVOID)m_pszSnapshotBuffer,0,m_nSnapshotBufferLen*sizeof(TCHAR)); m_nSnapshotStringLen = ::WideCharToMultiByte(CP_ACP,0,(LPWSTR)lpszString,nStringLen,(LPSTR)m_pszSnapshotBuffer,m_nSnapshotBufferLen,NULL,NULL); #endif //_UNICODE } else { #ifdef _UNICODE m_nSnapshotBufferLen = nStringLen; m_pszSnapshotBuffer = new TCHAR[m_nSnapshotBufferLen]; ::memset(m_pszSnapshotBuffer,0,m_nSnapshotBufferLen*sizeof(TCHAR)); m_nSnapshotStringLen = ::MultiByteToWideChar(CP_ACP,0,(LPCSTR)lpszString,nStringLen,m_pszSnapshotBuffer,m_nSnapshotBufferLen); #else m_nSnapshotBufferLen = nStringLen; m_pszSnapshotBuffer = new TCHAR[m_nSnapshotBufferLen]; ::memset((LPVOID)m_pszSnapshotBuffer,0,m_nSnapshotBufferLen*sizeof(TCHAR)); ::memcpy((LPVOID)m_pszSnapshotBuffer,lpszString,nStringLen); #endif //_UNICODE } } } void CHtmlObject::DeleteSnapshot() { // 。 InnerCleanupNode(); if( m_pszSnapshotBuffer ) delete []m_pszSnapshotBuffer; m_pszSnapshotBuffer = NULL; m_nSnapshotBufferLen = 0; m_nSnapshotStringLen = 0; } // void CHtmlObject::Parse() { #ifdef _AFX CString strTrace; strTrace.Format(_T("CHtmlObject::Parse() --begin-->(%d)\r
"),::GetTickCount()); ::OutputDebugString(strTrace); #endif //_AFX InnerParse(); #ifdef _AFX strTrace.Format(_T("CHtmlObject::Parse() --end-->(%d)\r
"),::GetTickCount()); ::OutputDebugString(strTrace); #endif //_AFX } // void CHtmlObject::InnerParse() { LPTSTR pszFind = m_pszSnapshotBuffer; // “ ” while( *pszFind != _T('\0') && CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } // '\0' do { // “\0”, “<” “\0”, 。 // InnerSplitContent() “<” “\0”。 if( *pszFind != _T('\0') && *pszFind == _T('<') ) { // “<” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; } // “\0” if( *pszFind != _T('\0') ) { // if( *pszFind == _T('!') ) { // 。 tagNode *pstNode = InnerAllocNode(); // , 。 pszFind = InnerSplitComment(pstNode,pszFind); // “ ”。( ) InnerLinkNextNode(pstNode); } else { // 。 tagNode *pstNode = InnerAllocNode(); // tag, tag 。 pszFind = InnerSplitTag(pstNode,pszFind); // content content 。 pszFind = InnerSplitContent(pstNode,pszFind); // “ ”。( ) InnerLinkNextNode(pstNode); } } }while( *pszFind!= _T('\0') ); } LPTSTR CHtmlObject::InnerSplitComment(CHtmlObject::tagNode * lpstNode,LPTSTR lpszTagString) { LPTSTR pszFind = lpszTagString; // ( “<” ) lpstNode->s_pszKey = pszFind; // <!-- *** --> if( ::_tcsnicmp(pszFind+1,_T("--"),2) == 0 ) { // “ ”, 。 pszFind += 3; // , “\0”。 while( ::_tcsnicmp(pszFind,_T("-->"),3) != 0 ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { // “>” “\0”, *(pszFind+2) = _T('\0'); // 。 pszFind += 3; } } // <! *** > else { // , “\0”。 while( *pszFind != _T('\0') && *pszFind != _T('>') ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { // “>” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; } } // “<” while( *pszFind != _T('\0') && *pszFind != _T('<') ) { // pszFind++; } return pszFind; } LPTSTR CHtmlObject::InnerSplitTag(CHtmlObject::tagNode * lpstNode,LPTSTR lpszTagString) { LPTSTR pszFind = lpszTagString; // ( “<” ) lpstNode->s_pszKey = pszFind; // tag , “\0”。 while( *pszFind != _T('\0') && *pszFind != _T('>') && !CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { if( *pszFind == _T('>') ) { // “>” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; // tag , 。 } else { // “space,\r,
,\t ” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; // , tag “ ” “ ”。 if( *lpstNode->s_pszKey != _T('/') ) { // “ ”, 。 while( *pszFind != _T('\0') && CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } // “ ”。 while( *pszFind != _T('\0') && *pszFind != _T('<') && *pszFind != _T('>') ) { // : // key="value" key=value // while( *pszFind != _T('\0') && CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { // 。 tagNode *pstAttributeNode = InnerAllocNode(); // “ ”Key。 pstAttributeNode->s_pszKey = pszFind; // key . while( *pszFind != _T('\0') && *pszFind != _T('=') && *pszFind != _T('>') ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { if( *pszFind == _T('>') ) { // “>” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; // “ ”( )。 InnerLinkRightNode(lpstNode,pstAttributeNode); // “>”, 。 break; } else { // “=” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; // “\0” if( *pszFind != _T('\0') ) { if( *pszFind == _T('"') ) { // “"” pszFind++; // “ ”key Value。 pstAttributeNode->s_pszValue = pszFind; // Value . while( *pszFind != _T('\0') && *pszFind != _T('\"') && *pszFind != _T('>') ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { // “",> ” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; } } else if( *pszFind == _T('\'') ) { // “'” pszFind++; // “ ”key Value。 pstAttributeNode->s_pszValue = pszFind; // Value . while( *pszFind != _T('\0') && *pszFind != _T('\'') && *pszFind != _T('>') ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { // “",<space> ” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; } } else { // “ ”key Value。 pstAttributeNode->s_pszValue = pszFind; // Value . while( *pszFind != _T('\0') && *pszFind != _T(' ') && *pszFind != _T('>') ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { // “ ” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; } } } } } // “ ”( )。 InnerLinkRightNode(lpstNode,pstAttributeNode); } } // 。 if( *pszFind == _T('>') ) { // 。 pszFind++; } } } } return pszFind; } LPTSTR CHtmlObject::InnerSplitContent(CHtmlObject::tagNode * lpstNode,LPTSTR lpszTagString) { LPTSTR pszFind = lpszTagString; if( ::_tcsnicmp(lpstNode->s_pszKey,_T("script"),6) == 0 ) { pszFind = InnerSplitScript(lpstNode,pszFind); } else if( ::_tcsnicmp(lpstNode->s_pszKey,_T("style"),5) == 0 ) { pszFind = InnerSplitStyle(lpstNode,pszFind); } else { pszFind = InnerSplitText(lpstNode,pszFind); } return pszFind; } LPTSTR CHtmlObject::InnerSplitText(CHtmlObject::tagNode * lpstNode,LPTSTR lpszTagString) { LPTSTR pszFind = lpszTagString; // “ ” while( *pszFind != _T('\0') && CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } // _T('<') 。 if( *pszFind != _T('<') ) { // 。 lpstNode->s_pszValue = pszFind; // 。 while( *pszFind != _T('\0') && *pszFind != _T('<') && !CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } // “\0” if( *pszFind != _T('\0') ) { if( *pszFind == _T('<') ) { // “<” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; } else { // “space,\r,
,\t,” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; // “<” while( *pszFind != _T('\0') && *pszFind != _T('<') ) { // pszFind++; } } } } return pszFind; } LPTSTR CHtmlObject::InnerSplitScript(tagNode * lpstNode,LPTSTR lpszTagString) { LPTSTR pszFind = lpszTagString; #define SCRIPT_MARK_MAX 1024 UINT nMarkIndex = 0; TCHAR szMark[SCRIPT_MARK_MAX] = {_T('\0')}; //max 1024 // “ ” while( *pszFind != _T('\0') && CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } if( *pszFind != _T('\0') && *pszFind != _T('<') ) { // 。 lpstNode->s_pszValue = pszFind; while( *pszFind != _T('\0') ) { // “',"” , 。 if( szMark[nMarkIndex] != _T('\'') && szMark[nMarkIndex] != _T('\"') ) { // // abc 。 if( ::_tcsnicmp(pszFind,_T("//"),2) == 0 ) { // “ ”。 pszFind +=2; // “ ”。 while( *pszFind != _T('\0') && *pszFind != _T('
') ) { pszFind++; } // “ ”。 if( *pszFind != _T('\0') ) pszFind++; } // /* abc */ 。 else if( ::_tcsnicmp(pszFind,_T("/*"),2) == 0 ) { // “ ”。 pszFind +=2; // “ ”。 while( ::_tcsnicmp(pszFind,_T("*/"),2) != 0 ) { pszFind++; } // “ ”。 if( *pszFind != _T('\0') ) pszFind +=2; } } if( *pszFind == _T('\\') && ( *(pszFind+1) == _T('\\') || *(pszFind+1) == _T('(') || *(pszFind+1) == _T(')') || *(pszFind+1) == _T('[') || *(pszFind+1) == _T(']') || *(pszFind+1) == _T('{') || *(pszFind+1) == _T('}') || *(pszFind+1) == _T('\'') || *(pszFind+1) == _T('\"') ) ) { // pszFind+=2; } else if( *pszFind == _T('{') || *pszFind == _T('(') || *pszFind == _T('[') || (*pszFind == _T('\'') || *pszFind == _T('\"')) ) { if( szMark[nMarkIndex] != _T('\'') && szMark[nMarkIndex] != _T('\"') ) { if( nMarkIndex < SCRIPT_MARK_MAX ) { if( nMarkIndex == 0 && szMark[nMarkIndex] == _T('\0') ) szMark[nMarkIndex] = *pszFind; else szMark[++nMarkIndex] = *pszFind; } } else if( szMark[nMarkIndex] == *pszFind ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T('}') ) { if( szMark[nMarkIndex] == _T('{') ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T(')') ) { if( szMark[nMarkIndex] == _T('(') ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T(']') ) { if( szMark[nMarkIndex] == _T('[') ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T('<') && szMark[0] == _T('\0') ) //nMarkIndex == 0 && { // “<” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; break; } else { pszFind++; } } } return pszFind; } LPTSTR CHtmlObject::InnerSplitStyle(CHtmlObject::tagNode * lpstNode,LPTSTR lpszTagString) { LPTSTR pszFind = lpszTagString; #define STYLE_MARK_MAX 1024 UINT nMarkIndex = 0; TCHAR szMark[STYLE_MARK_MAX] = {_T('\0')}; //max 1024 // “ ” while( *pszFind != _T('\0') && CHtmlObject::IsSpace(*pszFind) ) { // pszFind++; } if( *pszFind != _T('\0') && *pszFind != _T('<') ) { // 。 lpstNode->s_pszValue = pszFind; while( *pszFind != _T('\0') ) { // “(,',"” , 。 if( szMark[nMarkIndex] != _T('(') && szMark[nMarkIndex] != _T('\'') && szMark[nMarkIndex] != _T('\"') ) { // /* abc */ 。 if( ::_tcsnicmp(pszFind,_T("/*"),2) == 0 ) { // “ ”, “ ”。 pszFind +=2; while( ::_tcsnicmp(pszFind,_T("*/"),2) != 0 ) { pszFind++; } // “ ”。 if( *pszFind != _T('\0') ) pszFind +=2; } } if( *pszFind == _T('{') || *pszFind == _T('(') || *pszFind == _T('[') || (*pszFind == _T('\'') || *pszFind == _T('\"')) ) { if( szMark[nMarkIndex] != _T('\'') && szMark[nMarkIndex] != _T('\"') ) { if( nMarkIndex < STYLE_MARK_MAX ) { if( nMarkIndex == 0 && szMark[nMarkIndex] == _T('\0') ) szMark[nMarkIndex] = *pszFind; else szMark[++nMarkIndex] = *pszFind; } } else if( szMark[nMarkIndex] == *pszFind ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T('}') ) { if( szMark[nMarkIndex] == _T('{') ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T(')') ) { if( szMark[nMarkIndex] == _T('(') ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T(']') ) { if( szMark[nMarkIndex] == _T('[') ) { if( nMarkIndex >0 ) szMark[nMarkIndex--] = _T('\0'); else szMark[nMarkIndex] = _T('\0'); } pszFind++; } else if( *pszFind == _T('<') && szMark[0] == _T('\0') ) //nMarkIndex == 0 && { // “<” “\0”, 。 *pszFind = _T('\0'); // 。 pszFind++; break; } else { pszFind++; } } } return pszFind; } //////////////////////////////////////////////////////////////////////////////////////////CHtmlObject.cpp//////////////////////////////////////////////////////////////////////////
5:CHtmlHelperは派生クラスとして解析後の「タグ」と「属性」の読み取りを担当する.ここには2つの方法しか書かれていませんが、実際の応用は自分で追加してください.
//////////////////////////////////////////////////////////////////////////////////////////CHtmlHelper.h//////////////////////////////////////////////////////////////////////////

#pragma once

/*****************************************************************************************************************
created: 2011/12/03
author: hmm7e ([email protected])

*****************************************************************************************************************/

#include "HtmlObject.h"

class CHtmlHelper:public CHtmlObject
{
public:
	CHtmlHelper(void);
	virtual ~CHtmlHelper(void);
public:
	//
	LPCTSTR GetFirstLink();
	LPCTSTR GetNextLink();
	LPCTSTR GetFirstContent();
	LPCTSTR GetNextContent();
	LPCTSTR	SearchText(LPCTSTR lpszText);
protected:
	//
	CHtmlObject::tagNode * m_pstCur;
};



//////////////////////////////////////////////////////////////////////////////////////////CHtmlHelper.h//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////CHtmlHelper.cpp//////////////////////////////////////////////////////////////////////////

#pragma once

/*****************************************************************************************************************
created: 2011/12/03
author: hmm7e ([email protected])

*****************************************************************************************************************/


#include "HtmlHelper.h"

#pragma warning(disable: 4996) 

CHtmlHelper::CHtmlHelper()
{

}
CHtmlHelper::~CHtmlHelper()
{

}
//
LPCTSTR CHtmlHelper::GetFirstLink()
{
	LPCTSTR pszResult = NULL;

	m_pstCur = m_pstHead;

	while( m_pstCur && !pszResult )
	{
		if( 0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("script"),6) &&
			0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("style"),5) )
		{
			CHtmlObject::tagNode * pstAttributeCur = m_pstCur->s_pstRight;
			while( pstAttributeCur )
			{
				if( 0 == ::_tcsnicmp(pstAttributeCur->s_pszKey,_T("href"),4) ||
					0 == ::_tcsnicmp(pstAttributeCur->s_pszKey,_T("src"),3) )
				{
					//return
					pszResult = pstAttributeCur->s_pszValue;
					break ;
				}
				else
				{
					pstAttributeCur = pstAttributeCur->s_pstRight;
				}
			}
		}
		m_pstCur = m_pstCur->s_pstNext;
	}

	return pszResult;
}
LPCTSTR CHtmlHelper::GetNextLink()
{
	LPCTSTR pszResult = NULL;

	while( m_pstCur && !pszResult )
	{
		if( 0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("script"),6) &&
			0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("style"),5) )
		{
			CHtmlObject::tagNode * pstAttributeCur = m_pstCur->s_pstRight;
			while( pstAttributeCur )
			{
				if( 0 == ::_tcsnicmp(pstAttributeCur->s_pszKey,_T("href"),4) ||
					0 == ::_tcsnicmp(pstAttributeCur->s_pszKey,_T("src"),3) )
				{
					//return
					pszResult = pstAttributeCur->s_pszValue;
					break ;
				}
				else
				{
					pstAttributeCur = pstAttributeCur->s_pstRight;
				}
			}
		}

		m_pstCur = m_pstCur->s_pstNext;
	}

	return pszResult;
}
LPCTSTR CHtmlHelper::GetFirstContent()
{
	LPCTSTR pszResult = NULL;

	m_pstCur = m_pstHead;

	while( m_pstCur && !pszResult )
	{
		if( 0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("script"),6) &&
			0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("style"),5) )
		{
			if( m_pstCur->s_pszValue )
				pszResult = m_pstCur->s_pszValue;
		}

		m_pstCur = m_pstCur->s_pstNext;
	}

	return pszResult;
}
LPCTSTR CHtmlHelper::GetNextContent()
{
	LPCTSTR pszResult = NULL;

	while( m_pstCur && !pszResult )
	{
		if( 0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("script"),6) &&
			0 != ::_tcsnicmp(m_pstCur->s_pszKey,_T("style"),5) )
		{
			if( m_pstCur->s_pszValue )
				pszResult = m_pstCur->s_pszValue;
		}

		m_pstCur = m_pstCur->s_pstNext;
	}

	return pszResult;
}
//
LPCTSTR CHtmlHelper::SearchText(LPCTSTR lpszText)
{
	LPCTSTR pszResult = NULL;

	CHtmlObject::tagNode *pstCur = m_pstHead;

	while( pstCur && !pszResult)
	{
		if( 0 != ::_tcsnicmp(pstCur->s_pszKey,_T("script"),6) &&
			0 != ::_tcsnicmp(pstCur->s_pszKey,_T("style"),5) )
		{
			if( pstCur->s_pszValue )
			{
				if( (NULL != ::StrStrI(pstCur->s_pszValue,lpszText)) )
					pszResult = pstCur->s_pszValue;
			}
		}

		pstCur = pstCur->s_pstNext;
	}

	return pszResult;
}



#pragma warning(default: 4996) 



//////////////////////////////////////////////////////////////////////////////////////////CHtmlHelper.cpp//////////////////////////////////////////////////////////////////////////