⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.cpp

📁 相当不错的入门程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		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 + -