Xml 解析

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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值