📄 xml.cpp
字号:
pPrevAttrib=(LPXMLATTRIB)pPrevAttrib->m_pNext;
// 在当前父节点下以及指定属性后创建新属性
return AllocXmlAttrib(pParentNode,pPrevAttrib);
}
LPXMLNODE CXML::AllocXmlNode(LPXMLNODE pParentNode,LPXMLNODE pPrevNode)
{ // 分配空间
LPXMLNODE pXmlNode=(LPXMLNODE)m_heapXmlNodes.AllocUnit();
memset(pXmlNode,0,sizeof(XMLNODE));
// 按照链表进行保存(保持顺序,顺序向后添加)
pXmlNode->m_pHeapLink=NULL;
if(m_pNodeLinkLast!=NULL) m_pNodeLinkLast->m_pHeapLink=pXmlNode;
m_pNodeLinkLast=pXmlNode;
// 保留链表第一个单元的位置
if(m_pNodeLinks==NULL) m_pNodeLinks=m_pNodeLinkLast;
// 设置父节点和兄弟子节点
pXmlNode->m_pParent=pParentNode;
pXmlNode->m_pNext=NULL;
pXmlNode->m_pChild=NULL;
pXmlNode->m_pAttrib=NULL;
// 如果父节点存在,且没有子节点,设置子节点
if(pParentNode!=NULL&&pParentNode->m_pChild==NULL)
pParentNode->m_pChild=pXmlNode;
// 如果前一个节点存在,设置前一个节点的下一个节点
if(pPrevNode!=NULL)
{ ASSERT(pPrevNode->m_pParent==pParentNode);
ASSERT(pPrevNode->m_pNext==NULL);
pPrevNode->m_pNext=pXmlNode;
}
// 返回分配到的节点
return pXmlNode;
}
LPXMLATTRIB CXML::AllocXmlAttrib(LPXMLNODE pParentNode,LPXMLATTRIB pPrevAttrib)
{ // 分配空间
LPXMLATTRIB pXmlAttrib=(LPXMLATTRIB)m_heapXmlAttribs.AllocUnit();
memset(pXmlAttrib,0,sizeof(XMLATTRIB));
// 按照链表进行保存(保持顺序,顺序向后添加)
pXmlAttrib->m_pHeapLink=NULL;
if(m_pAttribLinkLast!=NULL) m_pAttribLinkLast->m_pHeapLink=pXmlAttrib;
m_pAttribLinkLast=pXmlAttrib;
// 保留链表第一个单元的位置
if(m_pAttribLinks==NULL) m_pAttribLinks=m_pAttribLinkLast;
// 如果前一个属性字段存在则进行穿链
pXmlAttrib->m_pNext=NULL;
if(pPrevAttrib!=NULL)
{ ASSERT(pPrevAttrib->m_pNext==NULL);
pPrevAttrib->m_pNext=pXmlAttrib;
}
// 如果父节点没有属性,则当前属性为他的第一个属性
if(pParentNode->m_pAttrib==NULL) pParentNode->m_pAttrib=pXmlAttrib;
// 返回分配的属性字段
return pXmlAttrib;
}
VOID CXML::FreeXmlStr(XMLSTR& XmlStr)
{
if(XmlStr.m_pStr!=NULL)
{ // 如果不是小字符串,则立即删除
if(!XmlStr.m_bSmallStr)
{ TFREE(XmlStr.m_pStr);
return;
}
// 否则字符串位于可用空间表中
m_heapXmlSmallStrs.FreeUnit((LPBYTE)XmlStr.m_pStr);
XmlStr.m_pStr=NULL;
}
}
VOID CXML::FreeXmlNode(LPXMLNODE pXmlNode)
{ if(pXmlNode!=NULL) FreeXmlStr(pXmlNode->m_Key);
m_heapXmlNodes.FreeUnit((LPBYTE)pXmlNode);
}
VOID CXML::FreeXmlAttrib(LPXMLATTRIB pXmlAttrib)
{ if(pXmlAttrib!=NULL)
{ FreeXmlStr(pXmlAttrib->m_Name);
FreeXmlStr(pXmlAttrib->m_Value);
}
m_heapXmlAttribs.FreeUnit((LPBYTE)pXmlAttrib);
}
// 文件读取回调函数
VOID CXML::SaveXmlNodeAndChilds(LPXMLNODE pNode,FILE* fpXml,LONG nLevel)
{
// 格式化缩进
CHAR szLine[2048]={0};
CHAR szIndent[MAX_PATH]={0};
if(nLevel!=0) memset(szIndent,'\t',min(nLevel,sizeof(szIndent)-1));
// 写入当前节点内容
switch(pNode->m_dwFlag)
{
case XMLNODE_SYSKEY:
{ // 写入本行,包括参数
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s<?%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"?>\r\n");
fwrite(szLine,strlen(szLine),1,fpXml);
}
break;
case XMLNODE_ITEMKEY:
{ // 写入本行,包括参数
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s</%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"/>\r\n");
fwrite(szLine,strlen(szLine),1,fpXml);
}
break;
case XMLNODE_KEYSET:
{ // 如果是附带数值的项目,作为一行写入,并忽略其全部子项
if(pNode->m_pChild==NULL||((LPXMLNODE)(pNode->m_pChild))->m_dwFlag==XMLNODE_VALUE)
{ // 构造头部数据
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s<%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
const char* pszValue="";
if(pNode->m_pChild!=NULL) pszValue=((LPXMLNODE)(pNode->m_pChild))->m_Key.m_pStr;
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,">%s</%s>\r\n",pszValue,pNode->m_Key.m_pStr);
fwrite(szLine,strlen(szLine),1,fpXml);
}
// 否则写入全部的子节点
else
{ // 写入本行,包括参数
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s<%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,">\r\n");
fwrite(szLine,strlen(szLine),1,fpXml);
// 处理全部子节点
LPXMLNODE pChildNode=(LPXMLNODE)pNode->m_pChild;
while(pChildNode!=NULL)
{ SaveXmlNodeAndChilds(pChildNode,fpXml,nLevel+1);
pChildNode=(LPXMLNODE)pChildNode->m_pNext;
}
// 写入本行结尾
szLine[0]='\0';
nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s</%s>\r\n",szIndent,pNode->m_Key.m_pStr);
fwrite(szLine,strlen(szLine),1,fpXml);
}
}
break;
case XMLNODE_VALUE:
// 数字不单独写入,附带KEYSEY一并写入
break;
}
}
// 输出XML流
VOID CXML::AppendXmls(char* lpszXmlBuf,LONG nXmlBufLen,LONG* pnUsed,const char* lpszAdd,LONG nAddLen)
{
// 判断缓冲区是否足够并复制缓冲区
LONG nFreeLen=(nXmlBufLen-(*pnUsed));
LONG nCopyLen=max(0,min(nFreeLen,nAddLen));
// 复制缓冲区并标记真实长度
if(nCopyLen>0) memcpy(lpszXmlBuf+(*pnUsed),lpszAdd,nCopyLen);
(*pnUsed)+=max(nAddLen,0);
}
// 流输出回调函数
VOID CXML::SaveXmlNodeAndChilds(LPXMLNODE pNode,char* lpszXmlBuf,LONG nXmlBufLen,LONG* pnUsed,LONG nLevel)
{
// 格式化缩进
CHAR szLine[2048]={0};
CHAR szIndent[MAX_PATH]={0};
if(nLevel!=0) memset(szIndent,'\t',min(nLevel,sizeof(szIndent)-1));
// 写入当前节点内容
switch(pNode->m_dwFlag)
{
case XMLNODE_SYSKEY:
{ // 写入本行,包括参数
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s<?%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"?>\r\n");
AppendXmls(lpszXmlBuf,nXmlBufLen,pnUsed,szLine,strlen(szLine));
}
break;
case XMLNODE_ITEMKEY:
{ // 写入本行,包括参数
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s</%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"/>\r\n");
AppendXmls(lpszXmlBuf,nXmlBufLen,pnUsed,szLine,strlen(szLine));
}
break;
case XMLNODE_KEYSET:
{ // 如果是附带数值的项目,作为一行写入,并忽略其全部子项
if(pNode->m_pChild==NULL||((LPXMLNODE)(pNode->m_pChild))->m_dwFlag==XMLNODE_VALUE)
{ // 构造头部数据
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s<%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
const char* pszValue="";
if(pNode->m_pChild!=NULL) pszValue=((LPXMLNODE)(pNode->m_pChild))->m_Key.m_pStr;
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,">%s</%s>\r\n",pszValue,pNode->m_Key.m_pStr);
AppendXmls(lpszXmlBuf,nXmlBufLen,pnUsed,szLine,strlen(szLine));
}
// 否则写入全部的子节点
else
{ // 写入本行,包括参数
szLine[0]='\0';
LONG nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s<%s",szIndent,pNode->m_Key.m_pStr);
LPXMLATTRIB pAttrib=(LPXMLATTRIB)pNode->m_pAttrib;
while(pAttrib!=NULL)
{ nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen," %s=\"%s\"",pAttrib->m_Name.m_pStr,pAttrib->m_Value.m_pStr);
pAttrib=(LPXMLATTRIB)pAttrib->m_pNext;
}
nLineLen=strlen(szLine);
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,">\r\n");
AppendXmls(lpszXmlBuf,nXmlBufLen,pnUsed,szLine,strlen(szLine));
// 处理全部子节点
LPXMLNODE pChildNode=(LPXMLNODE)pNode->m_pChild;
while(pChildNode!=NULL)
{ SaveXmlNodeAndChilds(pChildNode,lpszXmlBuf,nXmlBufLen,pnUsed,nLevel+1);
pChildNode=(LPXMLNODE)pChildNode->m_pNext;
}
// 写入本行结尾
szLine[0]='\0';
nLineLen=0;
nsprintf(szLine+nLineLen,sizeof(szLine)-nLineLen,"%s</%s>\r\n",szIndent,pNode->m_Key.m_pStr);
AppendXmls(lpszXmlBuf,nXmlBufLen,pnUsed,szLine,strlen(szLine));
}
}
break;
case XMLNODE_VALUE:
// 数字不单独写入,附带KEYSEY一并写入
break;
}
}
// 水印收集回调函数
/*VOID CXML::WaterMarkXmlNodeAndChilds(LPXMLNODE pNode,char** lppszBuffer,long* pnBufferSize,long* pnUsed)
{
// 忽略以下类型
if(pNode->m_dwFlag==XMLNODE_VALUE) return;
// 处理当前节点(包括其参数)
const char* lpszKey=pNode->m_Key.m_pStr;
const char* lpszValue=GetXmlNodeValue(pNode);
if(lpszKey==NULL) lpszKey="";
if(lpszValue==NULL) lpszValue="";
LONG nNeedSize=strlen(lpszKey)+strlen(lpszValue)+6;
// 如果缓冲区不足,扩大缓冲区
if((*pnBufferSize)-(*pnUsed)<nNeedSize)
{ char* pszOldBuffer=(*lppszBuffer);
DWORD dwRequreSize=(*pnBufferSize)+max(10*1024,nNeedSize);
(*lppszBuffer)=(char*)malloc(dwRequreSize);
if(pszOldBuffer!=NULL&&(*pnBufferSize)>0)
memcpy((*lppszBuffer),pszOldBuffer,(*pnBufferSize));
if(pszOldBuffer!=NULL)
free(pszOldBuffer);
(*pnBufferSize)+=max(10*1024,nNeedSize);
}
// 附加当前数据
nsprintf((*lppszBuffer)+(*pnUsed),(*pnBufferSize)-(*pnUsed),"<%s:%s>\r\n",lpszKey,lpszValue);
(*pnUsed)+=strlen((*lppszBuffer)+(*pnUsed));
// 遍历全部子节点
LPXMLNODE pChild=(LPXMLNODE)pNode->m_pChild;
while(pChild!=NULL)
{ WaterMarkXmlNodeAndChilds(pChild,lppszBuffer,pnBufferSize,pnUsed);
pChild=(LPXMLNODE)pChild->m_pNext;
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -