Ubuntu C语言 使用 libxml2库读写XML文件
参考自
http://www.codeweblog.com/linux%E4%B8%8B%E4%BD%BF%E7%94%A8libxml2%E5%BA%93%E8%AF%BB%E5%86%99xml%E6%96%87%E4%BB%B6/
但是在下载 libxml2-2.6.30.tar.gz 之后安装编译的时候 发现 问题:
In function 'open',
inlined from 'xmlNanoHTTPSave__internal_alias' at nanohttp.c:1588:12:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:50:4: error: call to '__open_missing_mode' declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments
__open_missing_mode ();
^
Makefile:853: recipe for target 'nanohttp.lo' failed
make[2]: *** [nanohttp.lo] Error 1
make[2]: Leaving directory '/home/hongzhunzhun/work/software/xml/libxml2-2.6.30'
Makefile:1017: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/hongzhunzhun/work/software/xml/libxml2-2.6.30'
Makefile:560: recipe for target 'all' failed
make: *** [all] Error 2
下载新版本 libxml2-2.6.30.tar.gz
http://linux.softpedia.com/get/Programming/Libraries/libxml2-162.shtml#download
./configure
make
sudo make install
新建一个xml文件夹
mkdir xml
新建一个xml 文件:List.xml
<?xml version="1.0"?> <List> <Person Id="1001" Name="Tsybius" Sex="Male" Age="23"> <Achievement>ABC Rank 2 </Achievement> <Achievement> DEF Rank 4 </Achievement> </Person> <Person Id="1002" Name="Galatea" Sex="Female" Age="21"> <Achievement>ABC Rank 1</Achievement> <Achievement>XYZ Rank 2</Achievement> <Achievement>MNOP Rank 5 </Achievement> </Person> </List>
a.c
#include<stdio.h> #include<libxml/parser.h> #include<libxml/tree.h> 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.c
#include<stdio.h> #include<stdlib.h> #include<libxml/parser.h> #include<libxml/tree.h> #define spc(level) PrintSpace(level) //输出缩进用的空格(4个) void PrintSpace(int level) { for(int counter = 0; counter < level; 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; }
make.sh
#!/bin/sh echo compiling... gcc a.c -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 -o a gcc b.c -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
sh make.sh