// 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 //======================================================== char* XNode::LoadAttributes( const char* pszAttrs, PARSEINFO *pi /*= &piDefault*/) { char* xml = (char*)pszAttrs; while( xml && *xml ) { xml = tcsskip( xml ); if( !xml ) continue; // close tag if( *xml == chXMLTagClose || *xml == chXMLTagPre || *xml == chXMLQuestion || *xml == chXMLDash ) // wel-formed tag return xml; // XML Attr Name char* pEnd = strpbrk( xml, " =" ); if( pEnd == NULL ) { // error if( !pi->error_occur ) { pi->error_occur = true; pi->error_pointer = xml; pi->error_code = PIE_ATTR_NO_VALUE; pi->error_string = ssprintf( ("<%s> attribute has error "), m_sName.c_str() ); } return NULL; } XAttr *attr = new XAttr; // XML Attr Name SetString( xml, pEnd, &attr->m_sName ); // add new attribute DEBUG_ASSERT( attr->m_sName.size() ); m_attrs.insert( pair<CString,XAttr*>(attr->m_sName, attr) ); xml = pEnd; // XML Attr Value xml = tcsskip( xml ); if( !xml ) continue; //if( xml = strchr( xml, '=' ) ) if( *xml == '=' ) { xml = tcsskip( ++xml ); if( !xml ) continue; // 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; char escape = pi->escape_value; //SetString( xml, pEnd, &attr->m_sValue, trim, chXMLEscape ); SetString( xml, pEnd, &attr->m_sValue, trim, escape ); xml = pEnd; // ATTRVALUE if( pi->entity_value && pi->entitys ) attr->m_sValue = pi->entitys->Ref2Entity(attr->m_sValue); if( quote == '"' || quote == '\'' ) xml++; } } // not well-formed tag return NULL; }
// <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 //======================================================== char* XNode::Load( const char* pszXml, PARSEINFO *pi /*= &piDefault*/ ) { Clear(); char* xml = (char*)pszXml; // < xml = strchr( xml, chXMLTagOpen ); if( xml == NULL ) return NULL; // </ if( xml[1] == chXMLTagPre ) return xml; /* <!-- */ if( !strncmp(xml+1, "!--", 3) ) { xml += 4; /* Find the close tag. */ char *pEnd = strstr( xml, "-->" ); if( pEnd == NULL ) { if( !pi->error_occur ) { pi->error_occur = true; pi->error_pointer = xml; pi->error_code = PIE_ALONE_NOT_CLOSED; pi->error_string = "Unterminated comment"; } return NULL; } // Skip -->. xml = pEnd + 3; return Load( xml, pi ); } // XML Node Tag Name Open xml++; char* pTagEnd = strpbrk( xml, " \t\r\n/>" ); SetString( xml, pTagEnd, &m_sName ); xml = pTagEnd; // Generate XML Attributte List xml = LoadAttributes( xml, pi ); if( xml == NULL ) return NULL; // alone tag <TAG ... /> or <?TAG ... ?> or <!-- ... --> // current pointer: ^ ^ ^ if( *xml == chXMLTagPre || *xml == chXMLQuestion || *xml == chXMLDash ) { xml++; // skip over 2nd dash if( *xml == chXMLDash ) xml++; if( *xml == chXMLTagClose ) { // well-formed tag ++xml; // UGLY: We want to ignore all XML meta tags. So, since the Node we // just loaded is a meta tag, then Load ourself again using the rest // of the file until we reach a non-meta tag. if( !m_sName.empty() && (m_sName[0] == chXMLQuestion || m_sName[0] == chXMLExclamation) ) xml = Load( xml, pi ); return xml; } else { // error: <TAG ... / > if( !pi->error_occur ) { pi->error_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 NULL; } } else // open/close tag <TAG ..> ... </TAG> // ^- current pointer { // text value╟║ ╬Ью╦╦│EЁж╣╣╥огя╢ы. //if( this->m_sValue.empty() || this->m_sValue == ("") ) if( XIsEmptyString( m_sValue ) ) { // Text Value char* pEnd = tcsechr( ++xml, chXMLTagOpen, chXMLEscape ); if( pEnd == NULL ) { if( !pi->error_occur ) { pi->error_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_CLOSED; pi->error_string = ssprintf( "%s must be closed with </%s>", m_sName.c_str(), m_sName.c_str() ); } // error cos not exist CloseTag </TAG> return NULL; } bool trim = pi->trim_value; char escape = pi->escape_value; //SetString( xml, pEnd, &m_sValue, trim, chXMLEscape ); SetString( xml, pEnd, &m_sValue, trim, escape ); xml = pEnd; // TEXTVALUE reference if( pi->entity_value && pi->entitys ) m_sValue = pi->entitys->Ref2Entity(m_sValue); } // generate child nodes while( xml && *xml ) { XNode *node = new XNode; xml = node->Load( xml,pi ); if( !node->m_sName.empty() ) { DEBUG_ASSERT( node->m_sName.size() ); m_childs.insert( pair<CString,XNode*>(node->m_sName, 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 xml = tcsskip( xml ); if( xml == NULL ) return NULL; CString closename; char* pEnd = strpbrk( xml, " >" ); if( pEnd == NULL ) { if( !pi->error_occur ) { pi->error_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_CLOSED; pi->error_string = ssprintf( "it must be closed with </%s>", m_sName.c_str() ); } // error return NULL; } SetString( xml, pEnd, &closename ); if( closename == this->m_sName ) { // wel-formed open/close xml = pEnd+1; // return '>' or ' ' after pointer return xml; } else { xml = pEnd+1; // not welformed open/close if( !pi->error_occur ) { pi->error_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_NESTED; pi->error_string = ssprintf( "'<%s> ... </%s>' is not well-formed.", m_sName.c_str(), closename.c_str() ); } return NULL; } } else // Alone child Tag Loaded // else гь╬ъго╢ба│E╦╩╬ф╬ъго╢ба│Eюг╫и╟ё╢ы. { //if( xml && this->m_sValue.empty() && *xml !=chXMLTagOpen ) if( xml && XIsEmptyString( m_sValue ) && *xml !=chXMLTagOpen ) { // Text Value char* pEnd = tcsechr( xml, chXMLTagOpen, chXMLEscape ); if( pEnd == NULL ) { // error cos not exist CloseTag </TAG> if( !pi->error_occur ) { pi->error_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_CLOSED; pi->error_string = ssprintf( "it must be closed with </%s>", m_sName.c_str() ); } return NULL; } bool trim = pi->trim_value; char escape = pi->escape_value; //SetString( xml, pEnd, &m_sValue, trim, chXMLEscape ); SetString( xml, pEnd, &m_sValue, trim, escape ); xml = pEnd; //TEXTVALUE if( pi->entity_value && pi->entitys ) m_sValue = pi->entitys->Ref2Entity(m_sValue); } } } } 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 //======================================================== char* XNode::Load( const char* pszXml, PARSEINFO *pi /*= &piDefault*/ ) { // Close it Close(); char* xml = (char*)pszXml; xml = strchr( xml, chXMLTagOpen ); if( xml == NULL ) return NULL; // Close Tag if( *(xml+1) == chXMLTagPre ) // </Close return xml; // XML Node Tag Name Open xml++; char* pTagEnd = strpbrk( xml, " />" ); SetString( xml, pTagEnd, &name ); xml = pTagEnd; // Generate XML Attributte List xml = LoadAttributes( xml, pi ); if( xml == NULL ) return NULL; // alone tag <TAG ... /> or <?TAG ... ?> if( *xml == chXMLTagPre || *xml == chXMLTagQuestion ) { xml++; if( *xml == chXMLTagClose ) { // wel-formed tag ++xml; // UGLY: We want to ignore all XML meta tags. So, since the Node we // just loaded is a meta tag, then Load ourself again using the rest // of the file until we reach a non-meta tag. if( !name.empty() && name[0] == chXMLTagQuestion ) xml = Load( xml, pi ); return xml; } else { // error: <TAG ... / > if( !pi->erorr_occur ) { 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 NULL; } } else // open/close tag <TAG ..> ... </TAG> // ^- current pointer { // text value╟║ ╬Ью╦╦│EЁж╣╣╥огя╢ы. //if( this->value.empty() || this->value == ("") ) if( XIsEmptyString( value ) ) { // Text Value char* pEnd = tcsechr( ++xml, chXMLTagOpen, chXMLEscape ); if( pEnd == NULL ) { if( !pi->erorr_occur ) { pi->erorr_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_CLOSED; pi->error_string = ssprintf( "%s must be closed with </%s>", name.c_str(), name.c_str() ); } // error cos not exist CloseTag </TAG> return NULL; } bool trim = pi->trim_value; char 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 ) { XNode *node = new XNode; node->parent = this; xml = node->Load( xml,pi ); if( !node->name.empty() ) { 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 xml = tcsskip( xml ); if( xml == NULL ) return NULL; CString closename; char* pEnd = strpbrk( xml, " >" ); if( pEnd == NULL ) { if( !pi->erorr_occur ) { pi->erorr_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_CLOSED; pi->error_string = ssprintf( "it must be closed with </%s>", name.c_str() ); } // 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; // not welformed open/close if( !pi->erorr_occur ) { pi->erorr_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_NESTED; pi->error_string = ssprintf( "'<%s> ... </%s>' is not well-formed.", name.c_str(), closename.c_str() ); } return NULL; } } else // Alone child Tag Loaded // else гь╬ъго╢ба│E╦╩╬ф╬ъго╢ба│Eюг╫и╟ё╢ы. { //if( xml && this->value.empty() && *xml !=chXMLTagOpen ) if( xml && XIsEmptyString( value ) && *xml !=chXMLTagOpen ) { // Text Value char* pEnd = tcsechr( xml, chXMLTagOpen, chXMLEscape ); if( pEnd == NULL ) { // error cos not exist CloseTag </TAG> if( !pi->erorr_occur ) { pi->erorr_occur = true; pi->error_pointer = xml; pi->error_code = PIE_NOT_CLOSED; pi->error_string = ssprintf( "it must be closed with </%s>", name.c_str() ); } return NULL; } bool trim = pi->trim_value; char escape = pi->escape_value; //SetString( xml, pEnd, &value, trim, chXMLEscape ); SetString( xml, pEnd, &value, trim, escape ); xml = pEnd; //TEXTVALUE if( pi->entity_value && pi->entitys ) value = pi->entitys->Ref2Entity(value); } } } } return xml; }