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//////////////////////////////////////////////////////////////////////////