1.安装、配置
sudo ./configure –prefix=/home/book/work/install_software/libxml2-2.7.8/temp –host=arm-linux-gnueabihf
sudo make
sudo make install
交叉编译工具链:
进入 temp/include目录
sudo cp libxml2 /usr/arm-linux-gnueabihf/include/ -rf
进入 temp/lib目录
sudo cp *.so /usr/arm-linux-gnueabihf/lib
PC 工具链:
sudo ./configure –prefix=/home/book/work/install_software/libxml2-2.7.8/pc_temp
sudo make
sudo make install
进入 pc_temp 目录中
sudo cp libxml /usr/include/ -rf
sudo cp *.so /usr/lib
在~/work/prac/xml$ gcc -o xmlparase2 xmlparase2.c -lxml2
gcc -o xmlparase2 xmlparase2.c -lxml2
XMl 例子程序:
2. 1 解析xml 文档例子:
Xml 文档内容如下:
<?xml version="1.0"?>
<story>
<storyinfo>
<author>John Fleck</author>
<datewritten>June 2, 2002</datewritten>
<keyword>example keyword</keyword>
</storyinfo>
<body>
<headline>This is the headline</headline>
<para>This is the body text.</para>
</body>
</story>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
/* 解析storyinfo节点,打印keyword节点的内容 */
void parseStory(xmlDocPtr doc, xmlNodePtr cur)
{
xmlChar* key;
cur=cur->xmlChildrenNode;
while(cur != NULL)
{
/* 找到keyword子节点 */
if(!xmlStrcmp(cur->name, (const xmlChar *)"keyword"))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
printf("keyword: %s\n", key);
xmlFree(key);
}
cur=cur->next; /* 下一个子节点 */
}
return;
}
/* 解析文档 */
static void parseDoc(char *docname)
{
/* 定义文档和节点指针 */
xmlDocPtr doc;
xmlNodePtr cur;
/* 进行解析,如果没成功,显示一个错误并停止 */
doc = xmlParseFile(docname);
if(doc == NULL)
{
fprintf(stderr, "Document not parse successfully. \n");
return;
}
/* 获取文档根节点,若无内容则释放文档树并返回 */
cur = xmlDocGetRootElement(doc);
if(cur == NULL)
{
fprintf(stderr, "empty document\n");
xmlFreeDoc(doc);
return;
}
/* 确定根节点名是否为story,不是则返回 */
if(xmlStrcmp(cur->name, (const xmlChar *)"story"))
{
fprintf(stderr, "document of the wrong type, root node != story");
xmlFreeDoc(doc);
return;
}
/* 遍历文档树 */
cur = cur->xmlChildrenNode;
while(cur != NULL)
{
/* 找到storyinfo子节点 */
if(!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))
{
parseStory(doc, cur); /* 解析storyinfo子节点 */
}
cur = cur->next; /* 下一个子节点 */
}
xmlFreeDoc(doc); /* 释放文档树 */
return;
}
int main(int argc, char **argv)
{
char *docname;
if(argc <= 1)
{
printf("Usage: %s docname\n", argv[0]);
return 0;
}
docname=argv[1];
parseDoc(docname);
return 1;
}
2.2 向xml文档中插入内容:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
void parseStory(xmlDocPtr doc, xmlNodePtr cur, const xmlChar* keyword)
{
/* 在当前节点下插入一个keyword子节点 */
xmlNewTextChild(cur, NULL, (const xmlChar*)"keyword", keyword);
return;
}
xmlDocPtr parseDoc(char *docname, char *keyword)
{
xmlDocPtr doc;
xmlNodePtr cur;
doc = xmlParseFile(docname);
if (doc == NULL ) {
fprintf(stderr,"Document not parsed successfully. \n");
return (NULL);
}
cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
fprintf(stderr,"empty document\n");
xmlFreeDoc(doc);
return (NULL);
}
if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {
fprintf(stderr,"document of the wrong type, root node != story");
xmlFreeDoc(doc);
return (NULL);
}
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){
parseStory (doc, cur, (const xmlChar*)keyword);
}
cur = cur->next;
}
return(doc);
}
int main(int argc, char **argv)
{
char *docname;
char *keyword;
xmlDocPtr doc;
if (argc <= 2) {
printf("Usage: %s docname, keyword\n", argv[0]);
return(0);
}
docname = argv[1];
keyword = argv[2];
doc = parseDoc(docname, keyword);
if (doc != NULL)
{
xmlSaveFormatFile(docname, doc, 0);
xmlFreeDoc(doc);
}
return (1);
}
编译: gcc -o insertToXml insertToXml.c -lxml2
执行: ./insertToXml xml.xml hellolxl 向 xml.xml <keyword> 节点中 插入 hellolxl 内容。
2.3 创建xml 文档:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>
#define PHONE_BOOK_FILE "phone_book.xml"
#define ID_STR_LEN 16
#define NAME_STR_LEN 32
#define TEL_STR_LEN 16
#define ADDR_STR_LEN 128
//电话通讯录结构体
typedef struct phone_t {
int id; //编号
char name[NAME_STR_LEN]; //姓名
char tel[TEL_STR_LEN]; //电话
char address[ADDR_STR_LEN]; //地址
}phone;
//设置通讯录项
static void set_phone_item(phone *phone_item)
{
assert(phone_item);
phone_item->id = 10;
snprintf(phone_item->name, NAME_STR_LEN, "%s", "Anker");
snprintf(phone_item->tel, TEL_STR_LEN, "%s", "13223246599");
snprintf(phone_item->address, ADDR_STR_LEN, "%s", "Shenzheng");
}
//创建phone节点
static xmlNodePtr create_phone_node(const phone *phone_item)
{
assert(phone_item);
char id[ID_STR_LEN] = {0};
xmlNodePtr phone_node = NULL;
phone_node = xmlNewNode(NULL, BAD_CAST"phone");
if (phone_node == NULL)
{
fprintf(stderr, "Failed to create new node.\n");
return NULL;
}
//设置属性
snprintf(id, ID_STR_LEN, "%d", phone_item->id);
xmlNewProp(phone_node, BAD_CAST"id", (xmlChar*)id);
xmlNewChild(phone_node, NULL, BAD_CAST"name", (xmlChar *)phone_item->name);
xmlNewChild(phone_node, NULL, BAD_CAST"tel", (xmlChar *)phone_item->tel);
xmlNewChild(phone_node, NULL, BAD_CAST"address", (xmlChar *)phone_item->address);
return phone_node;
}
//向根节点中添加一个phone节点
static int add_phone_node_to_root(xmlNodePtr root_node)
{
xmlNodePtr phone_node = NULL;
phone *phone_item = NULL;
//创建一个新的phone
phone_item = (phone *)malloc(sizeof(phone));
if (phone_item == NULL)
{
fprintf(stderr, "Failed to malloc memory.\n");
return -1;
}
set_phone_item(phone_item);
//创建一个phone节点
phone_node = create_phone_node(phone_item);
if (phone_node == NULL) {
fprintf(stderr, "Failed to create phone node.\n");
goto FAILED;
}
//根节点添加一个子节点
xmlAddChild(root_node, phone_node);
free(phone_item);
return 0;
FAILED:
if (phone_item){
free(phone_item);
}
return -1;
}
//创建phone_books
static int create_phone_books(const char *phone_book_file)
{
assert(phone_book_file);
xmlDocPtr doc = NULL;
xmlNodePtr root_node = NULL;
//创建一个xml 文档
doc = xmlNewDoc(BAD_CAST"1.0");
if (doc == NULL)
{
fprintf(stderr, "Failed to new doc.\n");
return -1;
}
//创建根节点
root_node = xmlNewNode(NULL, BAD_CAST"phone_books");
if (root_node == NULL)
{
fprintf(stderr, "Failed to new root node.\n");
goto FAILED;
}
//将根节点添加到文档中
xmlDocSetRootElement(doc, root_node);
if (add_phone_node_to_root(root_node) != 0)
{
fprintf(stderr, "Failed to add a new phone node.\n");
goto FAILED;
}
//将文档保存到文件中,按照utf-8编码格式保存
xmlSaveFormatFileEnc(phone_book_file, doc, "UTF-8", 1);
//xmlSaveFile("test.xml", doc);
xmlFreeDoc(doc);
return 0;
FAILED:
if (doc) {
xmlFreeDoc(doc);
}
return -1;
}
static int add_phone_node(const char *phone_book_file)
{
assert(phone_book_file);
xmlDocPtr doc = NULL;
xmlNodePtr root_node = NULL;
xmlNodePtr phone_node = NULL;
phone *phone_item = NULL;
doc = xmlParseFile(phone_book_file);
if (doc == NULL) {
fprintf(stderr, "Failed to parser xml file:%s\n", phone_book_file);
return -1;
}
root_node = xmlDocGetRootElement(doc);
if (root_node == NULL) {
fprintf(stderr, "Failed to get root node.\n");
goto FAILED;
}
if (add_phone_node_to_root(root_node) != 0) {
fprintf(stderr, "Failed to add a new phone node.\n");
goto FAILED;
}
//将文档保存到文件中,按照utf-8编码格式保存
xmlSaveFormatFileEnc(phone_book_file, doc, "UTF-8", 1);
xmlFreeDoc(doc);
return 0;
FAILED:
if (doc) {
xmlFreeDoc(doc);
}
return -1;
}
int main(int argc, char *argv[])
{
char *phone_book_file = PHONE_BOOK_FILE;
if (argc == 2)
{
phone_book_file = argv[1];
}
if (access(phone_book_file, F_OK) == 0)
{
//文件存在,添加一个新的phone节点
add_phone_node(phone_book_file);
}
else {
//文件不存在,创建一个信息的phone book
create_phone_books(phone_book_file);
}
return 0;
}
命令行执行: gcc -o create create.c -lxml2
第一次执行 ./create :
<?xml version="1.0" encoding="UTF-8"?>
<phone_books>
<phone id="10">
<name>Anker</name>
<tel>13223246599</tel>
<address>Shenzheng</address>
</phone>
</phone_books>
多次执行./create :
book@ubuntu:~/work/prac/xml/xml2$ cat phone_book.xml
<?xml version="1.0" encoding="UTF-8"?>
<phone_books>
<phone id="10">
<name>Anker</name>
<tel>13223246599</tel>
<address>Shenzheng</address>
</phone>
<phone id="10">
<name>Anker</name><tel>13223246599</tel><address>Shenzheng</address>
</phone>
<phone id="10">
<name>Anker</name><tel>13223246599</tel><address>Shenzheng</address></phone>
</phone_books>