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

📄 cutil-xml.c

📁 Linux环境下常用功能的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		pstruFile = stderr;
	}
	else
	{
		pstruFile = fopen(pszXmlFile, "w");
		if(pstruFile == NULL)
		{
			cutil_log_error(N_("create xml file %s error %s\n"), pszXmlFile, strerror(errno));
			return -1;
		}
	}
	in_xml_export_file(pstruXml, pstruFile, 0);
	fprintf(pstruFile, "\n");
	fflush(pstruFile);
	if(pszXmlFile != NULL)
		fclose(pstruFile);
	return 0;
}

/**
 * cutil_xml_destroy:
 * @pstruXml:包含数据的XML树.
 *
 * 消除XML结构的内存空间
 */
void cutil_xml_destroy(CutilXml * pstruXml)
{
	int i;

	if(pstruXml == NULL)
		return;

	if(pstruXml -> pstruFirstChild)
		cutil_xml_destroy(pstruXml -> pstruFirstChild);
	if(pstruXml -> pstruNext)
		cutil_xml_destroy(pstruXml -> pstruNext);

	for(i = 0 ; i < pstruXml -> nAttrNum; i ++)
	{
		if(pstruXml -> struAttr[i].pszAttrName)
			free(pstruXml -> struAttr[i].pszAttrName);
		if(pstruXml -> struAttr[i].pszAttrValue)
			free(pstruXml -> struAttr[i].pszAttrValue);
	}
	
	if(pstruXml -> pszElementName)
		free(pstruXml -> pszElementName);
	if(pstruXml -> pszElementValue)
		free(pstruXml -> pszElementValue);
	free(pstruXml);
}

/**
 * cutil_xml_select:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 *
 * 按照路径获取节点的值
 *
 * Returns: 成功返回节点的值,失败返回NULL
 */
const char * cutil_xml_select(CutilXml *pstruXml, const char *pszXpath)
{
	char *pszElementName;
	char *pszEnd;
	int nLen;

	if(pstruXml == NULL)
		return NULL;

	pszEnd = strchr(pszXpath, '/');
	if(pszEnd == NULL)
	{
		if(strcmp(pstruXml -> pszElementName, pszXpath) == 0)
			return pstruXml -> pszElementValue;
		return cutil_xml_select(pstruXml -> pstruNext, pszXpath);
	}

	nLen = pszEnd - pszXpath;
	pszElementName = (char *)calloc(1, nLen + 1);
	memcpy(pszElementName, pszXpath, nLen);

	if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
	{
		free(pszElementName);
		return cutil_xml_select(pstruXml -> pstruFirstChild, pszEnd + 1); 
	}
	while(pstruXml->pstruNext)
	{
		pstruXml = pstruXml->pstruNext;
		if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
		{
			free(pszElementName);
			return cutil_xml_select(pstruXml -> pstruFirstChild, pszEnd + 1); 	
		}
	}
	free(pszElementName);
	return NULL;
}

/**
 * cutil_xml_update:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 * @pszValue:节点的新值
 *
 * 按照路径更新节点的值
 *
 * Returns: 成功返回0,失败返回-1
 */
int cutil_xml_update(CutilXml *pstruXml, const char *pszXpath, const char *pszValue)
{
	char *pszElementName;
	char *pszEnd;
	int nLen;

	if(pstruXml == NULL)
		return -1;

	pszEnd = strchr(pszXpath, '/');
	if(pszEnd == NULL)
	{
		if(strcmp(pstruXml -> pszElementName, pszXpath) == 0)
		{
			if(pstruXml -> pszElementValue)
				free(pstruXml -> pszElementValue);
			pstruXml -> pszElementValue = strdup(pszValue);
			return 0;
		}
		return cutil_xml_update(pstruXml -> pstruNext, pszXpath, pszValue);
	}

	nLen = pszEnd - pszXpath;
	pszElementName = (char *)calloc(1, nLen + 1);
	memcpy(pszElementName, pszXpath, nLen);

	if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
	{
		free(pszElementName);
		return cutil_xml_update(pstruXml -> pstruFirstChild, pszEnd + 1, pszValue); 
	}
	while(pstruXml->pstruNext)
	{
		pstruXml = pstruXml->pstruNext;
		if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
		{
			free(pszElementName);
			return cutil_xml_update(pstruXml -> pstruFirstChild, pszEnd + 1, pszValue); 	
		}
	}
	free(pszElementName);
	return -1;
}

/**
 * cutil_xml_delete:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 *
 * 按照路径删除一个节点(TODO尚未实现该函数)
 *
 * Returns: 成功返回0,失败返回-1
 */
int cutil_xml_delete(CutilXml *pstruXml, const char *pszXpath)
{
	return -1;
}

/**
 * cutil_xml_insert:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 * @pszValue:要求插入的值
 *
 * 按照路径增加一个节点
 *
 * Returns: 成功返回的0,失败返回-1
 */
int cutil_xml_insert(CutilXml *pstruXml, const char *pszXpath, const char *pszValue)
{
	char *pszElementName;
	char *pszEnd;
	int nLen;

	if(pstruXml == NULL)
		return -1;

	pszEnd = strchr(pszXpath, '/');
	if(pszEnd == NULL)
	{		
		while(pstruXml -> pstruNext)
			pstruXml = pstruXml -> pstruNext;

		pstruXml -> pstruNext = (CutilXml *)calloc(1, sizeof(CutilXml));
		pstruXml -> pstruNext -> pszElementName = strdup(pszXpath);
		if(pszValue)
			pstruXml -> pstruNext -> pszElementValue = strdup(pszValue);
		else
			pstruXml -> pstruNext -> pszElementValue = NULL;
		pstruXml -> pstruNext -> nAttrNum = 0;
		pstruXml -> pstruNext -> pstruNext = NULL;
		pstruXml -> pstruNext -> pstruFirstChild = NULL;
		pstruXml -> pstruNext -> pstruParent = pstruXml -> pstruParent;
		
		return 0;
	}

	nLen = pszEnd - pszXpath;
	pszElementName = (char *)calloc(1, nLen + 1);
	memcpy(pszElementName, pszXpath, nLen);
	while(pstruXml)
	{
		if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
		{
			free(pszElementName);
			if(pstruXml -> pstruFirstChild)
				return cutil_xml_insert(pstruXml -> pstruFirstChild, pszEnd + 1, pszValue); 

			pszEnd ++;
			if(strchr(pszEnd, '/') != NULL)
				return -1;
			
			pstruXml -> pstruFirstChild = (CutilXml *)calloc(1, sizeof(CutilXml));
			pstruXml -> pstruFirstChild -> pszElementName = strdup(pszEnd);
			if(pszValue)
				pstruXml -> pstruFirstChild -> pszElementValue = strdup(pszValue);
			else
				pstruXml -> pstruFirstChild -> pszElementValue = NULL;
			pstruXml -> pstruFirstChild -> nAttrNum = 0;
			pstruXml -> pstruFirstChild -> pstruNext = NULL;
			pstruXml -> pstruFirstChild -> pstruFirstChild = NULL;
			pstruXml -> pstruFirstChild -> pstruParent = pstruXml;
			
			return 0;
		}
		pstruXml = pstruXml->pstruNext;
	}
	free(pszElementName);
	return -1;
}

/**
 * cutil_xml_attr_select:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 * @pszAttrName:属性的名称
 *
 * 按照路径获取节点的属性值
 *
 * Returns: 成功返回节点的属性值,失败返回NULL
 */
const char * cutil_xml_attr_select(CutilXml *pstruXml, const char *pszXpath, const char *pszAttrName)
{
	char *pszElementName;
	char *pszEnd;
	int nLen, i;

	if(pstruXml == NULL)
		return NULL;

	pszEnd = strchr(pszXpath, '/');
	if(pszEnd == NULL)
	{
		if(strcmp(pstruXml -> pszElementName, pszXpath) == 0)
		{
			for(i = 0 ; i < pstruXml -> nAttrNum ; i ++)
			{
				if(strcmp(pstruXml -> struAttr[i].pszAttrName, pszAttrName) == 0)
					return pstruXml -> struAttr[i].pszAttrValue;
			}
			return NULL;
		}
		return cutil_xml_attr_select(pstruXml -> pstruNext, pszXpath, pszAttrName);
	}

	nLen = pszEnd - pszXpath;
	pszElementName = (char *)calloc(1, nLen + 1);
	memcpy(pszElementName, pszXpath, nLen);

	if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
	{
		free(pszElementName);
		return cutil_xml_attr_select(pstruXml -> pstruFirstChild, pszEnd + 1, pszAttrName); 
	}
	while(pstruXml->pstruNext)
	{
		pstruXml = pstruXml->pstruNext;
		if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
		{
			free(pszElementName);
			return cutil_xml_attr_select(pstruXml -> pstruFirstChild, pszEnd + 1, pszAttrName); 	
		}
	}
	free(pszElementName);
	return NULL;
}

/**
 * cutil_xml_attr_update:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 * @pszAttrName:属性的名称
 * @pszValue:属性的新值
 *
 * 按照路径更新节点属性的值
 *
 * Returns: 成功返回0,失败返回-1
 */
int cutil_xml_attr_update(CutilXml *pstruXml, const char *pszXpath, const char *pszAttrName, const char *pszValue)
{
	char *pszElementName;
	char *pszEnd;
	int nLen, i;

	if(pstruXml == NULL)
		return -1;

	pszEnd = strchr(pszXpath, '/');
	if(pszEnd == NULL)
	{
		if(strcmp(pstruXml -> pszElementName, pszXpath) == 0)
		{
			for(i = 0 ; i < pstruXml -> nAttrNum ; i ++)
			{
				if(strcmp(pstruXml -> struAttr[i].pszAttrName, pszAttrName) == 0)
				{
					if(pstruXml -> struAttr[i].pszAttrValue)
						free(pstruXml -> struAttr[i].pszAttrValue);
					pstruXml -> struAttr[i].pszAttrValue = strdup(pszValue);
					return 0;
				}
			}
			return -1;
		}
		return cutil_xml_attr_update(pstruXml -> pstruNext, pszXpath, pszAttrName, pszValue);
	}

	nLen = pszEnd - pszXpath;
	pszElementName = (char *)calloc(1, nLen + 1);
	memcpy(pszElementName, pszXpath, nLen);

	if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
	{
		free(pszElementName);
		return cutil_xml_attr_update(pstruXml -> pstruFirstChild, pszEnd + 1, pszAttrName, pszValue); 
	}
	while(pstruXml->pstruNext)
	{
		pstruXml = pstruXml->pstruNext;
		if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
		{
			free(pszElementName);
			return cutil_xml_attr_update(pstruXml -> pstruFirstChild, pszEnd + 1, pszAttrName, pszValue); 	
		}
	}
	free(pszElementName);
	return -1;
}

/**
 * cutil_xml_attr_delete:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 * @pszAttrName:要求删除的属性
 *
 * 按照路径删除一个节点的属性(TODO尚未实现该函数)
 *
 * Returns: 成功返回0,失败返回-1
 */
int cutil_xml_attr_delete(CutilXml *pstruXml, const char *pszXpath, const char *pszAttrName)
{
	return -1;
}

/**
 * cutil_xml_attr_insert:
 * @pstruXml:包含数据的XML树.
 * @pszXpath:XML的路径比如 root/abc/def
 * @pszAttrName:要求插入的属性
 * @pszValue:要求插入的值
 *
 * 按照路径增加一个节点的属性
 *
 * Returns: 成功返回的0,失败返回-1
 */
int cutil_xml_attr_insert(CutilXml *pstruXml, const char *pszXpath, const char *pszAttrName, const char *pszValue)
{
	char *pszElementName;
	char *pszEnd;
	int nLen;

	if(pstruXml == NULL)
		return -1;

	pszEnd = strchr(pszXpath, '/');
	if(pszEnd == NULL)
	{
		if(strcmp(pstruXml -> pszElementName, pszXpath) == 0)
		{
			if(pstruXml -> nAttrNum >= MAX_ELEMENT_ATTR_NUM)
				return -1;
			pstruXml -> struAttr[pstruXml -> nAttrNum].pszAttrName = strdup(pszAttrName);
			pstruXml -> struAttr[pstruXml -> nAttrNum].pszAttrValue = strdup(pszValue);
			pstruXml -> nAttrNum ++;
			return 0;
		}
		return cutil_xml_attr_insert(pstruXml -> pstruNext, pszXpath, pszAttrName, pszValue);
	}

	nLen = pszEnd - pszXpath;
	pszElementName = (char *)calloc(1, nLen + 1);
	memcpy(pszElementName, pszXpath, nLen);

	if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
	{
		free(pszElementName);
		return cutil_xml_attr_insert(pstruXml -> pstruFirstChild, pszEnd + 1, pszAttrName, pszValue); 
	}
	while(pstruXml->pstruNext)
	{
		pstruXml = pstruXml->pstruNext;
		if(strcmp(pstruXml -> pszElementName, pszElementName) == 0)
		{
			free(pszElementName);
			return cutil_xml_attr_insert(pstruXml -> pstruFirstChild, pszEnd + 1, pszAttrName, pszValue); 	
		}
	}
	free(pszElementName);
	return -1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -