📄 xmlite.cpp
字号:
// XMLite.cpp: implementation of the XMLite class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XMLite.h"
#include <iostream>
#include <sstream>
#include <string>
#include <stdio>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
static const TCHAR chXMLTagOpen = '<';
static const TCHAR chXMLTagClose = '>';
static const TCHAR chXMLTagPre = '/';
static const TCHAR chXMLEscape = '\\'; // for value field escape
static const TCHAR szXMLPIOpen[] = _T("<?");
static const TCHAR szXMLPIClose[] = _T("?>");
static const TCHAR szXMLCommentOpen[] = _T("<!--");
static const TCHAR szXMLCommentClose[] = _T("-->");
static const TCHAR szXMLCDATAOpen[] = _T("<![CDATA[");
static const TCHAR szXMLCDATAClose[] = _T("]]>");
static const XENTITY x_EntityTable[] = {
{ '&', _T("&"), 5 } ,
{ '\"', _T("""), 6 } ,
{ '\'', _T("'"), 6 } ,
{ '<', _T("<"), 4 } ,
{ '>', _T(">"), 4 }
};
PARSEINFO piDefault;
DISP_OPT optDefault;
XENTITYS entityDefault((LPXENTITY)x_EntityTable, sizeof(x_EntityTable)/sizeof(x_EntityTable[0]) );
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//========================================================
// Name : _tcschrs
// Desc : same with _tcspbrk
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcschrs( LPCTSTR psz, LPCTSTR pszchs )
{
while( psz && *psz )
{
if( strchr( pszchs, *psz ) )
return (LPTSTR)psz;
psz++;
}
return NULL;
}
//========================================================
// Name : _tcsskip
// Desc : skip space
// Param :
// Return : skiped string
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsskip( LPCTSTR psz )
{
//while( psz && *psz == ' ' && *psz == 13 && *psz == 10 ) psz++;
while( psz && isspace(*psz) ) psz++;
return (LPTSTR)psz;
}
//========================================================
// Name : _tcsechr
// Desc : similar with _tcschr with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsechr( LPCTSTR psz, int ch, int escape )
{
LPTSTR pch = (LPTSTR)psz;
while( pch && *pch )
{
if( escape != 0 && *pch == escape )
pch++;
else
if( *pch == ch )
return (LPTSTR)pch;
pch++;
}
return pch;
}
//========================================================
// Name : _tcselen
// Desc : similar with _tcslen with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
int _tcselen( int escape, LPTSTR srt, LPTSTR end = NULL )
{
int len = 0;
LPTSTR pch = srt;
if( end==NULL ) end = (LPTSTR)sizeof(long);
LPTSTR prev_escape = NULL;
while( pch && *pch && pch<end )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
len++;
}
pch++;
}
return len;
}
//========================================================
// Name : _tcsecpy
// Desc : similar with _tcscpy with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
void _tcsecpy( LPTSTR psz, int escape, LPTSTR srt, LPTSTR end = NULL )
{
LPTSTR pch = srt;
if( end==NULL ) end = (LPTSTR)sizeof(long);
LPTSTR prev_escape = NULL;
while( pch && *pch && pch<end )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
*psz++ = *pch;
}
pch++;
}
*psz = '\0';
}
//========================================================
// Name : _tcsepbrk
// Desc : similar with _tcspbrk with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsepbrk( LPCTSTR psz, LPCTSTR chset, int escape )
{
LPTSTR pch = (LPTSTR)psz;
LPTSTR prev_escape = NULL;
while( pch && *pch )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
if( _tcschr( chset, *pch ) )
return (LPTSTR)pch;
}
pch++;
}
return pch;
}
//========================================================
// Name : _tcsenicmp
// Desc : similar with _tcsnicmp with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
int _tcsenicmp( LPCTSTR psz, LPCTSTR str, int len, int escape )
{
LPTSTR pch = (LPTSTR)psz;
LPTSTR prev_escape = NULL;
LPTSTR des = (LPTSTR)str;
int i = 0;
while( pch && *pch && i < len )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
if( tolower(*pch) != tolower(des[i]) )
break;
i++;
}
pch ++;
}
// find
if( i == len )
return 0;
if( psz[i] > des[i] )
return 1;
return -1;
}
//========================================================
// Name : _tcsenistr
// Desc : similar with _tcsistr with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsenistr( LPCTSTR psz, LPCTSTR str, int len, int escape )
{
LPTSTR pch = (LPTSTR)psz;
LPTSTR prev_escape = NULL;
LPTSTR des = (LPTSTR)str;
int i = 0;
while( pch && *pch )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
if( _tcsenicmp( pch, str, len, escape ) == 0 )
return (LPTSTR)pch;
}
pch++;
}
return pch;
}
//========================================================
// Name : _tcseistr
// Desc : similar with _tcsistr with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcseistr( LPCTSTR psz, LPCTSTR str, int escape )
{
int len = _tcslen( str );
return _tcsenistr( psz, str, len, escape );
}
//========================================================
// Name : _SetString
// Desc : put string of (psz~end) on ps string
// Param : trim - will be trim?
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
void _SetString( LPTSTR psz, LPTSTR end, CString* ps, bool trim = FALSE, int escape = 0 )
{
//trim
if( trim )
{
while( psz && psz < end && _istspace(*psz) ) psz++;
while( (end-1) && psz < (end-1) && _istspace(*(end-1)) ) end--;
}
int len = end - psz;
if( len <= 0 ) return;
if( escape )
{
len = _tcselen( escape, psz, end );
LPTSTR pss = ps->GetBufferSetLength( len );
_tcsecpy( pss, escape, psz, end );
}
else
{
LPTSTR pss = ps->GetBufferSetLength(len + 1 );
memcpy( pss, psz, len );
pss[len] = '\0';
}
}
_tagXMLNode::~_tagXMLNode()
{
Close();
}
void _tagXMLNode::Close()
{
for( int i = 0 ; i < childs.size(); i ++)
{
LPXNode p = childs[i];
if( p )
{
delete p; childs[i] = NULL;
}
}
childs.clear();
for( i = 0 ; i < attrs.size(); i ++)
{
LPXAttr p = attrs[i];
if( p )
{
delete p; attrs[i] = NULL;
}
}
attrs.clear();
}
// attr1="value1" attr2='value2' attr3=value3 />
// ^- return pointer
//========================================================
// Name : LoadAttributes
// Desc : loading attribute plain xml text
// Param : pszAttrs - xml of attributes
// pi = parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs , LPPARSEINFO pi /*= &piDefault*/)
{
LPTSTR xml = (LPTSTR)pszAttrs;
while( xml && *xml )
{
if( xml = _tcsskip( xml ) )
{
// close tag
if( *xml == chXMLTagClose || *xml == chXMLTagPre )
// wel-formed tag
return xml;
// XML Attr Name
TCHAR* pEnd = _tcspbrk( xml, " =" );
if( pEnd == NULL )
{
// error
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_ATTR_NO_VALUE;
pi->error_string.Format( _T("<%s> attribute has error "), name );
}
return NULL;
}
LPXAttr attr = new XAttr;
attr->parent = this;
// XML Attr Name
_SetString( xml, pEnd, &attr->name );
// add new attribute
attrs.push_back( attr );
xml = pEnd;
// XML Attr Value
if( xml = _tcsskip( xml ) )
{
//if( xml = _tcschr( xml, '=' ) )
if( *xml == '=' )
{
if( xml = _tcsskip( ++xml ) )
{
// if " or '
// or none quote
int quote = *xml;
if( quote == '"' || quote == '\'' )
pEnd = _tcsechr( ++xml, quote, chXMLEscape );
else
{
//attr= value>
// none quote mode
//pEnd = _tcsechr( xml, ' ', '\\' );
pEnd = _tcsepbrk( xml, _T(" >"), chXMLEscape );
}
bool trim = pi->trim_value;
TCHAR escape = pi->escape_value;
//_SetString( xml, pEnd, &attr->value, trim, chXMLEscape );
_SetString( xml, pEnd, &attr->value, trim, escape );
xml = pEnd;
// ATTRVALUE
if( pi->entity_value && pi->entitys )
attr->value = pi->entitys->Ref2Entity(attr->value);
if( quote == '"' || quote == '\'' )
xml++;
}
}
}
}
}
// not wel-formed tag
return NULL;
}
// attr1="value1" attr2='value2' attr3=value3 />
// ^- return pointer
//========================================================
// Name : LoadAttributes
// Desc : loading attribute plain xml text
// Param : pszAttrs - xml of attributes
// pszEnd - last string
// pi = parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs, LPCTSTR pszEnd, LPPARSEINFO pi /*= &piDefault*/ )
{
LPTSTR xml = (LPTSTR)pszAttrs;
while( xml && *xml )
{
if( xml = _tcsskip( xml ) )
{
// close tag
if( xml >= pszEnd )
// wel-formed tag
return xml;
// XML Attr Name
TCHAR* pEnd = _tcspbrk( xml, " =" );
if( pEnd == NULL )
{
// error
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -