📄 xmlite.cpp
字号:
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;
}
// <?xml version="1.0"?>
// ^- return pointer
//========================================================
// Name : LoadProcessingInstrunction
// Desc : loading processing instruction
// Param : pszXml - PI string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadProcessingInstrunction( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// find the end of pi
LPTSTR end = _tcsenistr( pszXml, szXMLPIClose, sizeof(szXMLPIClose)-1, pi ? pi->escape_value : 0 );
if( end == NULL )
return NULL;
// process pi
if( doc )
{
LPTSTR xml = (LPTSTR)pszXml;
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = XNODE_PI;
xml += sizeof(szXMLPIOpen)-1;
TCHAR* pTagEnd = _tcspbrk( xml, " ?>" );
_SetString( xml, pTagEnd, &node->name );
xml = pTagEnd;
node->LoadAttributes( xml, end, pi );
doc->childs.push_back( node );
}
end += sizeof(szXMLPIClose)-1;
return end;
}
// <!-- comment -->
// ^- return pointer
//========================================================
// Name : LoadComment
// Desc : loading comment
// Param : pszXml - comment string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadComment( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// find the end of comment
LPTSTR end = _tcsenistr( pszXml, szXMLCommentClose, sizeof(szXMLCommentClose)-1, pi ? pi->escape_value : 0 );
if( end == NULL )
return NULL;
// process comment
LPXNode par = parent;
if( parent == NULL && doc )
par = (LPXNode)&doc;
if( par )
{
LPTSTR xml = (LPTSTR)pszXml;
xml += sizeof(szXMLCommentOpen)-1;
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = XNODE_COMMENT;
node->name = _T("#COMMENT");
_SetString( xml, end, &node->value, FALSE );
par->childs.push_back( node );
}
end += sizeof(szXMLCommentClose)-1;
return end;
}
// <![CDATA[ cdata ]]>
// ^- return pointer
//========================================================
// Name : LoadCDATA
// Desc : loading CDATA
// Param : pszXml - CDATA string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadCDATA( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// find the end of CDATA
LPTSTR end = _tcsenistr( pszXml, szXMLCDATAClose, sizeof(szXMLCDATAClose)-1, pi ? pi->escape_value : 0 );
if( end == NULL )
return NULL;
// process CDATA
LPXNode par = parent;
if( parent == NULL && doc )
par = (LPXNode)&doc;
if( par )
{
LPTSTR xml = (LPTSTR)pszXml;
xml += sizeof(szXMLCDATAOpen)-1;
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = XNODE_CDATA;
node->name = _T("#CDATA");
_SetString( xml, end, &node->value, FALSE );
par->childs.push_back( node );
}
end += sizeof(szXMLCDATAClose)-1;
return end;
}
//========================================================
// Name : LoadOtherNodes
// Desc : internal function for loading PI/CDATA/Comment
// Param : node - current xml node
// pbRet - error occur
// pszXml - CDATA string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR LoadOtherNodes( LPXNode node, bool* pbRet, LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
LPTSTR xml = (LPTSTR)pszXml;
bool do_other_type = true;
*pbRet = false;
while( xml && do_other_type )
{
do_other_type = false;
xml = _tcsskip( xml );
LPTSTR prev = xml;
// is PI( Processing Instruction ) Node?
if( _tcsnicmp( xml, szXMLPIOpen, sizeof(szXMLPIOpen)-1 ) == 0 )
{
// processing instrunction parse
// return pointer is next node of pi
xml = node->LoadProcessingInstrunction( xml, pi );
//if( xml == NULL )
// return NULL;
// restart xml parse
}
if( xml != prev )
do_other_type = true;
xml = _tcsskip( xml );
prev = xml;
// is comment Node?
if( _tcsnicmp( xml, szXMLCommentOpen, sizeof(szXMLCommentOpen)-1 ) == 0 )
{
// processing comment parse
// return pointer is next node of comment
xml = node->LoadComment( xml, pi );
// comment node is terminal node
if( node->parent && node->parent->type != XNODE_DOC
&& xml != prev )
{
*pbRet = true;
return xml;
}
// restart xml parse when this node is root doc node
}
if( xml != prev )
do_other_type = true;
xml = _tcsskip( xml );
prev = xml;
// is CDATA Node?
if( _tcsnicmp( xml, szXMLCDATAOpen, sizeof(szXMLCDATAOpen)-1 ) == 0 )
{
// processing CDATA parse
// return pointer is next node of CDATA
xml = node->LoadCDATA( xml, pi );
// CDATA node is terminal node
if( node->parent && node->parent->type != XNODE_DOC
&& xml != prev )
{
*pbRet = true;
return xml;
}
// restart xml parse when this node is root doc node
}
if( xml != prev )
do_other_type = true;
}
return xml;
}
// <TAG attr1="value1" attr2='value2' attr3=value3 >
// </TAG>
// or
// <TAG />
// ^- return pointer
//========================================================
// Name : Load
// Desc : load xml plain text
// Param : pszXml - plain xml text
// pi = parser information
// Return : advanced string pointer (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tagXMLNode::Load( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// Close it
Close();
LPTSTR xml = (LPTSTR)pszXml;
xml = _tcschr( xml, chXMLTagOpen );
if( xml == NULL )
return NULL;
// Close Tag
if( *(xml+1) == chXMLTagPre ) // </Close
return xml;
// Load Other Node before <Tag>(pi, comment, CDATA etc)
bool bRet = false;
LPTSTR ret = NULL;
ret = LoadOtherNodes( this, &bRet, xml, pi );
if( ret != NULL )
xml = ret;
if( bRet )
return xml;
// XML Node Tag Name Open
xml++;
TCHAR* pTagEnd = _tcspbrk( xml, " />\t\r\n" );
_SetString( xml, pTagEnd, &name );
xml = pTagEnd;
// Generate XML Attributte List
if( xml = LoadAttributes( xml, pi ) )
{
// alone tag <TAG ... />
if( *xml == chXMLTagPre )
{
xml++;
if( *xml == chXMLTagClose )
// wel-formed tag
return ++xml;
else
{
// error: <TAG ... / >
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_ALONE_NOT_CLOSED;
pi->error_string = _T("Element must be closed.");
}
// not wel-formed tag
return NULL;
}
}
else
// open/close tag <TAG ..> ... </TAG>
// ^- current pointer
{
// if text value is not exist, then assign value
//if( this->value.IsEmpty() || this->value == _T("") )
if( XIsEmptyString( value ) )
{
// Text Value
TCHAR* pEnd = _tcsechr( ++xml, chXMLTagOpen, chXMLEscape );
if( pEnd == NULL )
{
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_CLOSED;
pi->error_string.Format(_T("%s must be closed with </%s>"), name );
}
// error cos not exist CloseTag </TAG>
return NULL;
}
bool trim = pi->trim_value;
TCHAR escape = pi->escape_value;
//_SetString( xml, pEnd, &value, trim, chXMLEscape );
_SetString( xml, pEnd, &value, trim, escape );
xml = pEnd;
// TEXTVALUE reference
if( pi->entity_value && pi->entitys )
value = pi->entitys->Ref2Entity(value);
}
// generate child nodes
while( xml && *xml )
{
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = type;
xml = node->Load( xml,pi );
if( node->name.IsEmpty() == FALSE )
{
childs.push_back( node );
}
else
{
delete node;
}
// open/close tag <TAG ..> ... </TAG>
// ^- current pointer
// CloseTag case
if( xml && *xml && *(xml+1) && *xml == chXMLTagOpen && *(xml+1) == chXMLTagPre )
{
// </Close>
xml+=2; // C
if( xml = _tcsskip( xml ) )
{
CString closename;
TCHAR* pEnd = _tcspbrk( xml, " >" );
if( pEnd == NULL )
{
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_CLOSED;
pi->error_string.Format(_T("it must be closed with </%s>"), name );
}
// error
return NULL;
}
_SetString( xml, pEnd, &closename );
if( closename == this->name )
{
// wel-formed open/close
xml = pEnd+1;
// return '>' or ' ' after pointer
return xml;
}
else
{
xml = pEnd+1;
// 2004.6.15 - example <B> alone tag
// now it can parse with attribute 'force_arse'
if( pi->force_parse == false )
{
// not welformed open/close
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_NESTED;
pi->error_string.Format(_T("'<%s> ... </%s>' is not wel-formed."), name, closename );
}
return NULL;
}
}
}
}
else // Alone child Tag Loaded
// else 秦具窍绰瘤 富酒具窍绰瘤 狼缴埃促.
{
//if( xml && this->value.IsEmpty() && *xml !=chXMLTagOpen )
if( xml && XIsEmptyString( value ) && *xml !=chXMLTagOpen )
{
// Text Value
TCHAR* pEnd = _tcsechr( xml, chXMLTagOpen, chXMLEscape );
if( pEnd == NULL )
{
// error cos not exist CloseTag </TAG>
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_CLOSED;
pi->error_string.Format(_T("it must be closed with </%s>"), name );
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -