解决方案 »
- 对话框销毁的问题及对话框之间传递数据
- MFC界面求助
- 照《MFC深入详解》做例题,出了Debug assertion Failed错误,求助
- 急用,如何用AfxMessageBox()显示一个整数变量的值?
- 求教 VC6.0转VC7.0问题
- 一个关于strFilter和mpset.Update()的问题
- 怎样编译VXD和屏保?请高手指点!
- 我想得到本机的计算机名字,gethostbyname(),可以得到英文的,可是如果是中文的名字,就不行了,哪为知道用什么函数可以
- 线程池调度算法。?
- Win7下注册COM组件问题
- 怎么点击按钮使整个对话框不可用且变灰
- MFC应用程序, 支持ActiveX就等于支持Automation吗?
第三个函数:
int CMarkup::x_InsertNew( int iPosParent, int& iPosRel, NodePos& node )
{
// Parent empty tag or tags with no content?
bool bEmptyParentTag = iPosParent && ELEM(iPosParent).IsEmptyElement();
bool bNoContentParentTags = iPosParent && ! ELEM(iPosParent).ContentLen();
if ( iPosRel && ! node.nLength ) // current position element?
{
node.nStart = ELEM(iPosRel).nStart;
if ( ! (node.nNodeFlags & MNF_INSERT) ) // follow iPosRel
node.nStart += ELEM(iPosRel).nLength;//*/////////////////////////////////////////////////////////////////////////////
// Add by CLin
// 偏移换行符"\r\n", 在下面的"token.WhitespaceToTag( node.nStart )"处就不作偏移
node.nStart += MCD_PSZLEN( x_EOL );
//*/////////////////////////////////////////////////////////////////////////////
}
else if ( bEmptyParentTag ) // parent has no separate end tag?
{
// Split empty parent element
if ( ELEM(iPosParent).nFlags & MNF_NONENDED )
node.nStart = ELEM(iPosParent).StartContent();
else
node.nStart = ELEM(iPosParent).StartContent() - 1;
}
else if ( node.nLength || (m_nDocFlags&MDF_WRITEFILE) ) // non-element node or a file mode zero length position?
{
if ( ! (node.nNodeFlags & MNF_INSERT) )
node.nStart += node.nLength; // after node or file mode position
}
else // no current node
{
// Insert relative to parent's content
if ( node.nNodeFlags & (MNF_INSERT|MNF_REPLACE) )
node.nStart = ELEM(iPosParent).StartContent(); // beginning of parent's content
else // in front of parent's end tag
node.nStart = ELEM(iPosParent).StartAfter() - ELEM(iPosParent).EndTagLen();
} // Go up to start of next node, unless its splitting an empty element
if ( ! (node.nNodeFlags&(MNF_WITHNOLINES|MNF_REPLACE)) && ! bEmptyParentTag )
{
TokenPos token( m_strDoc, m_nDocFlags );
//*/////////////////////////////////////////////////////////////////////////
// Modify by CLin
// 当该元素拥有兄弟元素时, 不调整节点nStart(上面已经调整过)
// 这里其实也是调整的作用, 但是如果在这里调整会跳过缩进的空格符 // node.nStart = token.WhitespaceToTag( node.nStart );
if ( iPosRel != 0 && node.nNodeFlags != 16384 )
node.nStart = token.WhitespaceToTag( node.nStart );
//*//////////////////////////////////////////////////////////////////////////
} // Is insert relative to element position? (i.e. not other kind of node)
if ( ! node.nLength )
{
// Modify iPosRel to reflect position before
if ( iPosRel )
{
if ( node.nNodeFlags & MNF_INSERT )
{
if ( ! (ELEM(iPosRel).nFlags & MNF_FIRST) )
iPosRel = ELEM(iPosRel).iElemPrev;
else
iPosRel = 0;
}
}
else if ( ! (node.nNodeFlags & MNF_INSERT) )
{
// If parent has a child, add after last child
if ( ELEM(iPosParent).iElemChild )
iPosRel = ELEM(ELEM(iPosParent).iElemChild).iElemPrev;
}
} // Get node length (needed for x_AddNode and x_AddSubDoc in file write mode)
node.nLength = MCD_STRLENGTH(node.strMeta); // Prepare end of lines
if ( (! (node.nNodeFlags & MNF_WITHNOLINES)) && (bEmptyParentTag || bNoContentParentTags) )
node.nStart += x_EOLLEN;
if ( ! (node.nNodeFlags & MNF_WITHNOLINES) )
node.strMeta += x_EOL; // Calculate insert offset and replace length
int nReplace = 0;
int nInsertAt = node.nStart;
if ( bEmptyParentTag )
{
MCD_STR strTagName = x_GetTagName( iPosParent );
MCD_STR strFormat;
if ( node.nNodeFlags & MNF_WITHNOLINES )
strFormat = MCD_T(">");
else
strFormat = MCD_T(">") x_EOL; strFormat += node.strMeta;//*//////////////////////////////////////////////////////////////////
// Add by CLin
// 添加子元素后, 会加上父元素的结束标签"</....."
// 此处为父元素的结束标签增加了缩进
int iLevel = x_GetNodeLevel( iPosParent );
for (int iCount=0; iCount<iLevel; iCount++)
strFormat += x_INDENT;
//*///////////////////////////////////////////////////////////////////
strFormat += MCD_T("</");
strFormat += strTagName;
node.strMeta = strFormat;
if ( ELEM(iPosParent).nFlags & MNF_NONENDED )
{
nInsertAt = ELEM(iPosParent).StartAfter() - 1;
nReplace = 0;
ELEM(iPosParent).nFlags ^= MNF_NONENDED;
}
else
{
int i = m_strDoc.Find("<"+strTagName);
nInsertAt = ELEM(iPosParent).StartAfter() - 2;
nReplace = 1;
ELEM(iPosParent).AdjustStartTagLen( -1 );
}
ELEM(iPosParent).SetEndTagLen( 3 + MCD_STRLENGTH(strTagName) );
}
else
{
if ( node.nNodeFlags & MNF_REPLACE )
{
nInsertAt = ELEM(iPosParent).StartContent();
nReplace = ELEM(iPosParent).ContentLen();
}
else if ( bNoContentParentTags )
{
node.strMeta = x_EOL + node.strMeta;
nInsertAt = ELEM(iPosParent).StartContent();
}
}
if ( m_nDocFlags & MDF_WRITEFILE )
{
// Check if buffer is full
int nNewDocLength = MCD_STRLENGTH(m_strDoc) + MCD_STRLENGTH(node.strMeta) - nReplace;
int nFlushTo = node.nStart;
MCD_STRCLEAR( m_strResult );
if ( bEmptyParentTag )
nFlushTo = ELEM(iPosParent).nStart;
if ( nFlushTo && nNewDocLength > m_pFilePos->m_nBlockSizeBasis )
{
int nDocCapacity = MCD_STRCAPACITY(m_strDoc);
if ( nNewDocLength > nDocCapacity )
{
if ( bEmptyParentTag )
ELEM(iPosParent).nStart = 0;
node.nStart -= nFlushTo;
nInsertAt -= nFlushTo;
m_pFilePos->FileFlush( m_strDoc, nFlushTo );
m_strResult = m_pFilePos->m_strIOResult;
}
}
} x_DocChange( nInsertAt, nReplace, node.strMeta );
return nReplace;
}
第二段代码好像显示的有点问题,,重新贴下MCD_STR CMarkup::x_GetTagName( int iPos ) const
{
// Return the tag name at specified element
TokenPos token( m_strDoc, m_nDocFlags );
token.m_nNext = ELEM(iPos).nStart + 1;//*////////////////////////////////////////////////////////////////////////
// Add by CLin
// 因为在元素起始标签加入了缩进, 在获取元素名的时候可能会获取错误, 返回"<"
// 此处加入一个偏移, 获取元素名的时候偏移掉缩进量, 防止上述问题
while ( token.m_pDocText[token.m_nNext - 1 ] != '<' )
token.m_nNext ++;
//*//////////////////////////////////////////////////////////////////////// if ( ! iPos || ! token.FindName() )
return MCD_T(""); // Return substring of document
return token.GetTokenText();
}
bool CMarkup::x_AddElem( MCD_PCSZ pName, MCD_PCSZ pValue, int nFlags )
{
if ( m_nDocFlags & MDF_READFILE )
return false;
if ( nFlags & MNF_CHILD )
{
// Adding a child element under main position
if ( ! m_iPos || (m_nDocFlags & MDF_WRITEFILE) )
return false;
} // Cannot have data in non-ended element
if ( (nFlags&MNF_WITHNOEND) && pValue && pValue[0] )
return false; // Node and element structures
NodePos node( nFlags );
int iPosParent = 0, iPosBefore = 0;
int iPos = x_GetFreePos();
ElemPos* pElem = &ELEM(iPos); // Locate where to add element relative to current node
if ( nFlags & MNF_CHILD )
{
iPosParent = m_iPos;
iPosBefore = m_iPosChild;
}
else
{
iPosParent = m_iPosParent;
iPosBefore = m_iPos;
node.nStart = m_nNodeOffset;
node.nLength = m_nNodeLength;
} // Create string for insert
// If no pValue is specified, an empty element is created
// i.e. either <NAME>value</NAME> or <NAME/>
////*///////////////////////////////////////////////////////////////////
// Add by CLin 2013/10/10
// 添加元素时根据元素的节点等级确定缩进量 MCD_STR strBeginTag;
int iLevel;
int iIndentLen; strBeginTag.Format("<");
iLevel = 0;
iIndentLen = 0;
if ( !(iPosParent == 0 && iPosBefore == 0) )
{
strBeginTag.Empty();
iLevel = x_GetNodeLevel( iPosParent );
for (int iCount=0; iCount<iLevel+1; iCount++)
strBeginTag += x_INDENT; iIndentLen = strBeginTag.GetLength();
strBeginTag += "<";
}
//*///////////////////////////////////////////////////////////////////// int nLenName = MCD_PSZLEN(pName);
if ( ! pValue || ! pValue[0] )
{
// <NAME/> empty element
//*///////////////////////////////////////////////////////////////////
// Modify by CLin 2013/10/10
// 根据不同缩进量分配内存
// 并加上尖括号 // MCD_BLDRESERVE( node.strMeta, nLenName + 4 );
// MCD_BLDAPPEND1( node.strMeta, '<' );
// MCD_BLDAPPENDN( node.strMeta, pName, nLenName );
MCD_BLDRESERVE( node.strMeta, nLenName + 4 + iIndentLen);
MCD_BLDAPPENDN( node.strMeta, strBeginTag, iIndentLen + 1 );
MCD_BLDAPPENDN( node.strMeta, pName, nLenName );
//*/////////////////////////////////////////////////////////////////// if ( nFlags & MNF_WITHNOEND )
{
MCD_BLDAPPEND1( node.strMeta, '>' );
}
else
{
if ( nFlags & MNF_WITHXHTMLSPACE )
{
MCD_BLDAPPENDN( node.strMeta, MCD_T(" />"), 3 );
}
else
{
MCD_BLDAPPENDN( node.strMeta, MCD_T("/>"), 2 );
}
}
MCD_BLDRELEASE( node.strMeta );
pElem->nLength = MCD_STRLENGTH( node.strMeta );
pElem->SetStartTagLen( pElem->nLength );
pElem->SetEndTagLen( 0 );
}
else
{
// <NAME>value</NAME>
MCD_STR strValue;
if ( nFlags & MNF_WITHCDATA )
strValue = x_EncodeCDATASection( pValue );
else
strValue = EscapeText( pValue, nFlags );
int nLenValue = MCD_STRLENGTH(strValue);//*///////////////////////////////////////////////////////////////////
// Modify by CLin
// 根据不同缩进量分配内存
// 并加上尖括号 // pElem->nLength = nLenName * 2 + nLenValue + 5;
// MCD_BLDRESERVE( node.strMeta, pElem->nLength );
// MCD_BLDAPPEND1( node.strMeta, '<' );
// MCD_BLDAPPENDN( node.strMeta, pName, nLenName );
pElem->nLength = nLenName * 2 + nLenValue + 5 + iIndentLen;
MCD_BLDRESERVE( node.strMeta, pElem->nLength );
MCD_BLDAPPENDN( node.strMeta, strBeginTag, iIndentLen + 1 );
MCD_BLDAPPENDN( node.strMeta, pName, nLenName );
//*///////////////////////////////////////////////////////////////////
MCD_BLDAPPEND1( node.strMeta, '>' );
MCD_BLDAPPENDN( node.strMeta, MCD_2PCSZ(strValue), nLenValue );
MCD_BLDAPPENDN( node.strMeta, MCD_T("</"), 2 );
MCD_BLDAPPENDN( node.strMeta, pName, nLenName );
MCD_BLDAPPEND1( node.strMeta, '>' );
MCD_BLDRELEASE( node.strMeta );
pElem->SetEndTagLen( nLenName + 3 );
pElem->SetStartTagLen( nLenName + 2 );
} // Insert
int nReplace = x_InsertNew( iPosParent, iPosBefore, node );
pElem->nStart = node.nStart;
pElem->iElemChild = 0;
if ( nFlags & MNF_WITHNOEND )
pElem->nFlags = MNF_NONENDED;
else
pElem->nFlags = 0;
if ( m_nDocFlags & MDF_WRITEFILE )
{
iPosParent = x_UnlinkPrevElem( iPosParent, iPosBefore, iPos );
TokenPos token( m_strDoc, m_nDocFlags );
token.m_nL = pElem->nStart + 1;
token.m_nR = pElem->nStart + nLenName;
m_pFilePos->m_elemstack.PushTagAndCount( token );
}
else
{
x_LinkElem( iPosParent, iPosBefore, iPos );
x_Adjust( iPos, MCD_STRLENGTH(node.strMeta) - nReplace );
}
if ( nFlags & MNF_CHILD )
x_SetPos( m_iPosParent, iPosParent, iPos );
else
x_SetPos( iPosParent, iPos, 0 );
return true;
}
只是因为是基于CMarkup来修改
如果直接等它Save之后再处理的话就需要考虑到文件会越来越大的问题,会严重影响效率
而如果希望在每次添加元素的时候进行处理
就需要更新其中的某些成员变量,所以看起来比较麻烦,但是不会影响效率