目录结构:
将xml.c 与 user.xml 置于同一目录下即可
代码: xml.c
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
typedef struct userMsg
{
char user[20];
char pw[20];
} userMsg_t;
int AppSetUser(char *account, char *parma, char *value)
{
xmlDocPtr pdoc = NULL; //文档指针
xmlNodePtr proot = NULL, pcur = NULL; //根节点以及当前位置
char filename[] = "user.xml";
//防止程序将元素之前和之后的空白文本符号视为节点
xmlKeepBlanksDefault(0);
pdoc = xmlReadFile(filename, "UTF-8", XML_PARSE_RECOVER); //读取文档
if (pdoc == NULL)
{
printf("error:can't open file!\n");
return -1;
}
proot = xmlDocGetRootElement(pdoc);
if (proot == NULL)
{
printf("error:can't read root node!\n");
return -1;
}
pcur = proot->xmlChildrenNode;
while (pcur != NULL)
{
if (!xmlStrcmp(pcur->name, BAD_CAST("user"))) //找到第一个节点
{
xmlNodePtr nptr = pcur->xmlChildrenNode;
while (pcur != NULL)
{
userMsg_t *tmpMsg;
if (!xmlStrcmp(nptr->name, BAD_CAST("account"))) //找到子节点,我是根据需求,需要找到对应的账号,再设置节点的值
{
char *tempAccount = "";
tempAccount = ((char *)XML_GET_CONTENT(nptr->xmlChildrenNode));
if (strncmp(tempAccount, account, sizeof(tempAccount)) == 0) //判断账号是否匹配
{
nptr = nptr->next;
//在下面做一个循环,指向account后面的节点,可以根据节点的名称设置对应的值
while (nptr != NULL)
{
if (!xmlStrcmp(nptr->name, BAD_CAST(parma)))
{
printf("set parma: parma -> %s,value-> %s\n", parma, value);
xmlNodeSetContent(nptr, value);
// xmlSetProp(nptr,parma,value) 这个可以设置节点的属性值,读者可以自己去试一下
nptr = nptr->next;
xmlFreeDoc(pdoc);
xmlCleanupParser();
xmlMemoryDump();
return 1;
}
}
break;
}
}
}
pcur = pcur->next;
}
//释放资源
xmlFreeDoc(pdoc);
xmlCleanupParser();
xmlMemoryDump();
return 1;
}
}
int main()
{
AppSetUser("3001", "password", "5678");
}
xml文件: user.xml
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<user>
<account>3001</account>
<password>333</password>
</user>
<user>
<account>3002</account>
<password>3002</password>
</user>
</bookstore>
编译: gcc -o main xml.c -I/usr/include -lxml2 -Wl,-rpath /usr/lib
运行: ./main