INXString CMarkup::x_GetData( int iPos ) const { // Return a string representing data between start and end tag // Return empty string if there are any children elements if ( ! m_aPos[iPos].iElemChild && ! m_aPos[iPos].IsEmptyElement() ) { // See if it is a CDATA section const char* tempCh = (const char*)m_csDoc; char* szDoc = (char*)tempCh; int nChar = m_aPos[iPos].nStartR + 1; if ( x_FindAny( szDoc, nChar ) && szDoc[nChar] == '<' && nChar + 11 < m_aPos[iPos].nEndL && strncmp( &szDoc[nChar], "<![CDATA[",9) == 0) { nChar += 9; int nEndCDATA = m_csDoc.Finds("]]>", nChar); if ( nEndCDATA != -1 && nEndCDATA < m_aPos[iPos].nEndL ) { return m_csDoc.Mid( nChar, nEndCDATA - nChar ); } } return x_TextFromDoc( m_aPos[iPos].nStartR+1, m_aPos[iPos].nEndL-1 ); } INXString temp(""); return temp; }
CString CMarkup::x_GetData( int iPos ) const { // Return a string representing data between start and end tag // Return empty string if there are any children elements if ( ! m_aPos[iPos].iElemChild && ! m_aPos[iPos].IsEmptyElement() ) { // See if it is a CDATA section LPCTSTR szDoc = (LPCTSTR)m_csDoc; int nChar = m_aPos[iPos].nStartR + 1; if ( x_FindAny( szDoc, nChar ) && szDoc[nChar] == _T('<') && nChar + 11 < m_aPos[iPos].nEndL && _tcsncmp( &szDoc[nChar], _T("<![CDATA["), 9 ) == 0 ) { nChar += 9; int nEndCDATA = m_csDoc.Find( _T("]]>"), nChar ); if ( nEndCDATA != -1 && nEndCDATA < m_aPos[iPos].nEndL ) { return m_csDoc.Mid( nChar, nEndCDATA - nChar ); } } return x_TextFromDoc( m_aPos[iPos].nStartR+1, m_aPos[iPos].nEndL-1 ); } return _T(""); }
bool CMarkup::x_FindToken( CMarkup::TokenPos& token ) { // Starting at token.nNext, bypass whitespace and find the next token // returns true on success, members of token point to token // returns false on end of document, members point to end of document char* szDoc = token.szDoc; int nChar = token.nNext; token.bIsString = false; // By-pass leading whitespace if ( ! x_FindAny(szDoc,nChar) ) { // No token was found before end of document token.nL = nChar; token.nR = nChar; token.nNext = nChar; return false; } // Is it an opening quote? char cFirstChar = szDoc[nChar]; if ( cFirstChar == _T('\"') || cFirstChar == _T('\'') ) { token.bIsString = true; // Move past opening quote ++nChar; token.nL = nChar; // Look for closing quote x_FindChar( token.szDoc, nChar, cFirstChar ); // Set right to before closing quote token.nR = nChar - 1; // Set nChar past closing quote unless at end of document if ( szDoc[nChar] ) ++nChar; } else { // Go until special char or whitespace token.nL = nChar; while ( szDoc[nChar] && ! strchr(" \t\n\r<>=\\/?!",szDoc[nChar]) ) nChar += _tclen(&szDoc[nChar]); // Adjust end position if it is one special char if ( nChar == token.nL ) ++nChar; // it is a special char token.nR = nChar - 1; } // nNext points to one past last char of token token.nNext = nChar; return true; }
void CMarkup::x_LocateNew( int iPosParent, int& iPosRel, int& nOffset, int nLength, int nFlags ) { // Determine where to insert new element or node // bool bInsert = (nFlags&1)?true:false; bool bHonorWhitespace = (nFlags&2)?true:false; int nStartL; if ( nLength ) { // Located at a non-element node if ( bInsert ) nStartL = nOffset; else nStartL = nOffset + nLength; } else if ( iPosRel ) { // Located at an element if ( bInsert ) // precede iPosRel nStartL = m_aPos[iPosRel].nStartL; else // follow iPosRel nStartL = m_aPos[iPosRel].nEndR + 1; } else if ( ! iPosParent ) { // Outside of all elements if ( bInsert ) nStartL = 0; else nStartL = m_csDoc.GetLength(); } else if ( m_aPos[iPosParent].IsEmptyElement() ) { // Parent has no separate end tag, so split empty element nStartL = m_aPos[iPosParent].nStartR; } else { if ( bInsert ) // after start tag nStartL = m_aPos[iPosParent].nStartR + 1; else // before end tag nStartL = m_aPos[iPosParent].nEndL; } // Go up to start of next node, unless its splitting an empty element if ( ! bHonorWhitespace && ! m_aPos[iPosParent].IsEmptyElement() ) { char* szDoc = (char*)m_csDoc; int nChar = nStartL; if ( ! x_FindAny(szDoc,nChar) || szDoc[nChar] == _T('<') ) nStartL = nChar; } // Determine iPosBefore int iPosBefore = 0; if ( iPosRel ) { if ( bInsert ) { // Is iPosRel past first sibling? int iPosPrev = m_aPos[iPosParent].iElemChild; if ( iPosPrev != iPosRel ) { // Find previous sibling of iPosRel while ( m_aPos[iPosPrev].iElemNext != iPosRel ) iPosPrev = m_aPos[iPosPrev].iElemNext; iPosBefore = iPosPrev; } } else { iPosBefore = iPosRel; } } else if ( m_aPos[iPosParent].iElemChild ) { if ( ! bInsert ) { // Find last element under iPosParent int iPosLast = m_aPos[iPosParent].iElemChild; int iPosNext = iPosLast; while ( iPosNext ) { iPosLast = iPosNext; iPosNext = m_aPos[iPosNext].iElemNext; } iPosBefore = iPosLast; } } nOffset = nStartL; iPosRel = iPosBefore; }
int CMarkup::x_ParseNode( CMarkup::TokenPos& token ) { // Call this with token.nNext set to the start of the node // This returns the node type and token.nNext set to the char after the node // If the node is not found or an element, token.nR is not determined int nTypeFound = 0; char* szDoc = token.szDoc; token.nL = token.nNext; if ( szDoc[token.nL] == '<' ) { // Started with <, could be: // <!--...--> comment // <!DOCTYPE ...> dtd // <?target ...?> processing instruction // <![CDATA[...]]> cdata section // <NAME ...> element // if ( ! szDoc[token.nL+1] || ! szDoc[token.nL+2] ) return 0; char cFirstChar = szDoc[token.nL+1]; char* szEndOfNode = NULL; if ( cFirstChar == '?') { nTypeFound = MNT_PROCESSING_INSTRUCTION; szEndOfNode = (char*)("?>"); } else if ( cFirstChar == '!' ) { char cSecondChar = szDoc[token.nL+2]; if ( cSecondChar == '[' ) { nTypeFound = MNT_CDATA_SECTION; szEndOfNode = (char*)("]]>"); } else if ( cSecondChar == '-') { nTypeFound = MNT_COMMENT; szEndOfNode = "-->"; } else { // Document type requires tokenizing because of strings and brackets nTypeFound = 0; int nBrackets = 0; while ( x_FindToken(token) ) { if ( ! token.bIsString ) { char cChar = szDoc[token.nL]; if ( cChar == '[') ++nBrackets; else if ( cChar == ']' ) --nBrackets; else if ( nBrackets == 0 && cChar == _T('>') ) { nTypeFound = MNT_DOCUMENT_TYPE; break; } } } if ( ! nTypeFound ) return 0; } } else if ( cFirstChar == '/') { // End tag means no node found within parent element return 0; } else { nTypeFound = MNT_ELEMENT; } // Search for end of node if not found yet if ( szEndOfNode ) { char* pEnd = strstr( &szDoc[token.nNext], szEndOfNode ); if ( ! pEnd ) return 0; // not well-formed token.nNext = (pEnd - szDoc) + strlen(szEndOfNode); } } else if ( szDoc[token.nL] ) { // It is text or whitespace because it did not start with < nTypeFound = MNT_WHITESPACE; token.nNext = token.nL; if ( x_FindAny(szDoc,token.nNext) ) { if ( szDoc[token.nNext] != _T('<') ) { nTypeFound = MNT_TEXT; x_FindChar( szDoc, token.nNext, _T('<') ); } } } return nTypeFound; }