📄 cutil-xml.c
字号:
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 + -