一、安装libxml2库
在linux对XML文件进行增、删、改、查,需要使用库libxml2
我下载的文件是libxml2-2.6.30.tar.gz,将它放到到自己的Linux环境中,解压文件:
tar -xzvf libxml2-2.6.30.tar.gz
进入解压后的文件,依次输入命令安装:
./configure
make
make install
如果想检查安装效果可以输入命令:
make tests
卸载已安装的库可以输入命令
make uninstall
安装后的库,会被安放在两个地方:
*.h文件会被放到地址 /usr/local/include/libxml2/libxml
*.so文件会被放到地址 /usr/local/lib
二、源码一(a.cpp)
a.cpp建立了一个XML文档,根节点List,下面有2个Person,每个Person下有若干属性和若干Achievement作为子结点
#include
#include
#include
int main()
{
//建立XML文档和根结点
xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
xmlNodePtr root = xmlNewNode(NULL, BAD_CAST"List");
//将根节点绑定到XML文档
xmlDocSetRootElement(doc, root);
//建立Person结点,为其安装四个属性
xmlNodePtr nodeTsybius = xmlNewNode(NULL, BAD_CAST"Person");
xmlNewProp(nodeTsybius, BAD_CAST"Id", BAD_CAST"1001");
xmlNewProp(nodeTsybius, BAD_CAST"Name", BAD_CAST"Tsybius");
xmlNewProp(nodeTsybius, BAD_CAST"Sex", BAD_CAST"Male");
xmlNewProp(nodeTsybius, BAD_CAST"Age", BAD_CAST"23");
xmlAddChild(root, nodeTsybius);
//在Person结点下安放子结点,并为子节点添加内容
xmlNewTextChild(nodeTsybius, NULL, BAD_CAST"Achievement", BAD_CAST"ABC Rank 2");
xmlNewTextChild(nodeTsybius, NULL, BAD_CAST"Achievement", BAD_CAST"DEF Rank 4");
xmlNodePtr nodeGalatea = xmlNewNode(NULL, BAD_CAST"Person");
xmlNewProp(nodeGalatea, BAD_CAST"Id", BAD_CAST"1002");
xmlNewProp(nodeGalatea, BAD_CAST"Name", BAD_CAST"Galatea");
xmlNewProp(nodeGalatea, BAD_CAST"Sex", BAD_CAST"Female");
xmlNewProp(nodeGalatea, BAD_CAST"Age", BAD_CAST"21");
xmlAddChild(root, nodeGalatea);
xmlNewTextChild(nodeGalatea, NULL, BAD_CAST"Achievement", BAD_CAST"ABC Rank 1");
xmlNewTextChild(nodeGalatea, NULL, BAD_CAST"Achievement", BAD_CAST"XYZ Rank 2");
xmlNewTextChild(nodeGalatea, NULL, BAD_CAST"Achievement", BAD_CAST"MNOP Rank 5");
//保存XML文档
int nRel = xmlSaveFile("List.xml", doc);
if(nRel != -1)
{
printf("List.xml: Created Successfully!\n");
}
//释放资源
xmlFreeDoc(doc);
xmlCleanupParser();
return 0;
}
三、源码二(b.cpp)
b.cpp对a.cpp中建立的XML文档进行修改
#include
#include
#include
#include
#define spc(level) PrintSpace(level)
//输出缩进用的空格(4个)
void PrintSpace(int level)
{
for(int counter = 0; counter {
printf(" ");
}
}
//主函数
int main()
{
//打开XML文件
xmlDocPtr doc = xmlParseFile("List.xml");
if(doc == NULL)
{
printf("Error: Can not open List.xml\n");
exit(1);
}
//找到首结点
xmlNodePtr root = xmlDocGetRootElement(doc);
if(root == NULL)
{
printf("Error: Can not find the root!\n");
exit(1);
}
xmlNodePtr person; //Person结点指针
xmlNodePtr achivm; //Achievement结点指针
//遍历一个Person结点
spc(0); printf("Name: %s\n", root -> name);
person = root -> children;
//逐个找出属性
spc(1); printf("Node: %s\n", person -> name);
spc(2); printf("Id: %s\n", xmlGetProp(person, BAD_CAST "Id"));
spc(2); printf("Name: %s\n", xmlGetProp(person, BAD_CAST "Name"));
spc(2); printf("Sex: %s\n", xmlGetProp(person, BAD_CAST "Sex"));
spc(2); printf("Age: %s\n", xmlGetProp(person, BAD_CAST "Age"));
//用循环遍历子节点,打印内容
for(achivm = person -> children; achivm; achivm = achivm -> next)
{
spc(3);
printf("Node: %s\t", achivm -> name);
printf("Content: %s\t", (char*)xmlNodeGetContent(achivm));
printf("End\n");
}
spc(1); printf("End\n");
//一个Person结点遍历结束
//转到下一个Person结点
person = person -> next;
//查看某属性是否与某字符串相等
if(xmlStrcmp(xmlGetProp(person, BAD_CAST "Name"), (const xmlChar*)"Galate"))
{
spc(1); printf(">> The next person is Galatea!\n");
}
else
{
spc(1); printf(">> The next person is not Galatea!\n");
}
//查看某结点是否有某属性
if(xmlHasProp(person, BAD_CAST "Height"))
{
spc(1); printf(">> The node person has attribute: Height!\n");
}
else
{
spc(1); printf(">> The next person does not have attribute: Height!\n");
}
//修改属性(Attribute)
xmlSetProp(person, (const xmlChar*)"Age", (const xmlChar*)"22");
spc(1); printf(">> Change Galatea's age from 21 to 22!\n");
//修改子结点中的内容(Content)
xmlNodeSetContent(person -> children, (const xmlChar*) "NEW Rank 1");
spc(1); printf(">> Change Galatea's 1st achievement to NEW Rank 1\n");
//打印修改后的person结点
spc(1); printf("Node: %s\n", person -> name);
spc(2); printf("Id: %s\n", xmlGetProp(person, BAD_CAST "Id"));
spc(2); printf("Name: %s\n", xmlGetProp(person, BAD_CAST "Name"));
spc(2); printf("Sex: %s\n", xmlGetProp(person, BAD_CAST "Sex"));
spc(2); printf("Age: %s\n", xmlGetProp(person, BAD_CAST "Age"));
for(achivm = person -> children; achivm; achivm = achivm -> next)
{
spc(3);
printf("Node: %s\t", achivm -> name);
printf("Content: %s\t", (char*)xmlNodeGetContent(achivm));
printf("End\n");
}
spc(1); printf("End\n");
spc(0); printf("End\n");
xmlFree(achivm);
xmlFree(person);
xmlFree(root);
xmlFree(doc);
xmlCleanupParser();
return 0;
}
四、编译
在a.cpp和b.cpp同一个目录下建立一个文件compile.sh,内容如下:
#!/bin/sh
echo compiling...
g++ a.cpp -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 -o a
g++ b.cpp -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 -o b
echo run a...
./a
cat List.xml
echo run b...
./b
exit 0
在命令行中输入下面命令编译a.cpp和b.cpp
/bin/sh compile.sh
五、运行结果
![318ea812ef8fd17b97321ac822f3d909.png](https://img.php1.cn/3cd4a/1eebe/cd5/5b97d3b808d031e2.webp)
END
来源:oschina
链接:https://my.oschina.net/u/1425762/blog/309665