// <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(" />\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, pi ? pi->escape_value : 0 ); 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, pi ? pi->escape_value : 0 ); _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 ) ) { HM::String closename; TCHAR* pEnd = _tcspbrk( xml, _T(" >") ); 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, pi ? pi->escape_value : 0 ); 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; } bool trim = pi->trim_value; TCHAR escape = pi->escape_value; //_SetString( xml, pEnd, &value, trim, pi ? pi->escape_value : 0 ); _SetString( xml, pEnd, &value, trim, escape ); xml = pEnd; //TEXTVALUE if( pi->entity_value && pi->entitys ) value = pi->entitys->Ref2Entity(value); } } } } } return xml; }
// <TAG attr1="value1" attr2='value2' attr3=value3 > // </TAG> // or // <TAG /> // ^- return pointer //======================================================== // Desc : load xml plain text // Param : pszXml - plain xml text // pi = parser information // Return : advanced std::string pointer //======================================================== char* _tagXMLNode::load( const char* pszXml, LPPARSEINFO pi /*= &piDefault*/ ) { char* xml = (char*)pszXml; // initilize parent = NULL; childs.clear(); attrs.clear(); xml = _tcschr( xml, chXMLTagOpen ); if( xml == NULL ) return xml; // Close Tag if( *(xml+1) == chXMLTagPre ) // </Close return xml; // XML Node Tag Name Open xml++; char* pTagEnd = _tcspbrk( xml, " />" ); _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 = "Element must be closed."; } // not wel-formed tag return xml; } } else // open/close tag <TAG ..> ... </TAG> // ^- current pointer { // insert if no text value if( this->value.empty() ) { // Text Value char* 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 = "%s must be closed with </%s>", name; pi->error_string += name; } // error cos not exist CloseTag </TAG> return xml; } bool trim = pi->trim_value; _Setstring( xml, pEnd, &value, trim, chXMLEscape ); xml = pEnd; // TEXTVALUE reference if( pi->entity_value && pi->entitys ) value = pi->entitys->ref2Entity(value.c_str()); } // generate child nodes while( xml && *xml ) { LPXNode node = new XNode; node->parent = this; xml = node->load( xml,pi ); if( node->name.empty() == FALSE ) { std::transform( node->name.begin(), node->name.end(), node->name.begin(), static_cast<int(*)(int)>(::tolower) ); //node->name.MakeLower(); 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 ) ) { std::string closename; char* 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 = "it must be closed with"; pi->error_string += name; } // error return xml; } _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; // 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 = name + "..." + closename + " is not wel-formed."; } return xml; } } } else // Alone child Tag Loaded { if( xml && this->value.empty() && *xml !=chXMLTagOpen ) { // Text Value char* 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 = "it must be closed with"+ name; } return xml; } bool trim = pi->trim_value; _Setstring( xml, pEnd, &value, trim, chXMLEscape ); xml = pEnd; //TEXTVALUE if( pi->entity_value && pi->entitys ) value = pi->entitys->ref2Entity(value.c_str()); } } } } } return xml; }
// 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, _T(" =") ); 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, pi ? pi->escape_value : 0 ); else { //attr= value> // none quote mode //pEnd = _tcsechr( xml, ' ', '\\' ); pEnd = _tcsepbrk( xml, _T(" >"), pi ? pi->escape_value : 0 ); } bool trim = pi->trim_value; TCHAR escape = pi->escape_value; //_SetString( xml, pEnd, &attr->value, trim, pi ? pi->escape_value : 0 ); _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 //======================================================== // Desc : loading attribute plain xml text // Param : pszAttrs - xml of attributes // pi = parser information // Return : advanced std::string pointer. //======================================================== char* _tagXMLNode::loadAttributes( const char* pszAttrs , LPPARSEINFO pi /*= &piDefault*/) { char* xml = (char*)pszAttrs; while( xml && *xml ) { if( xml = _tcsskip( xml ) ) { if ( xml = _tctskip(xml) ) { if ( xml = _tcrskip(xml) ) { // close tag if( *xml == chXMLTagClose || *xml == chXMLTagPre ) // wel-formed tag return xml; // XML Attr Name char* 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 = "<%s> attribute has error "; pi->error_string += name; } return xml; } 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, " >", chXMLEscape ); } bool trim = pi->trim_value; _Setstring( xml, pEnd, &attr->value, trim, chXMLEscape ); xml = pEnd; // ATTRVALUE if( pi->entity_value && pi->entitys ) attr->value = pi->entitys->ref2Entity(attr->value.c_str()); if( quote == '"' || quote == '\'' ) xml++; } } } } } } } // not wel-formed tag return NULL; }