linux下使用libxml2庫讀寫XML文件

1、安裝libxml2庫node

在linux對XML文件進行增、刪、改、查,須要使用庫libxml2linux

這個庫能夠在地址:ftp.gnome.org/pub/GNOME/sources/libxml2/2.6/ 下載,bash

我下載的文件是libxml2-2.6.30.tar.gz,將它放到到本身的Linux環境中,解壓文件:函數

tar -xzvf libxml2-2.6.30.tar.gz

進入解壓後的文件,依次輸入命令安裝:spa

./configure
make
make install

若是想檢查安裝效果能夠輸入命令:命令行

make tests

卸載已安裝的庫能夠輸入命令指針

make uninstall

安裝後的庫,會被安放在兩個地方:code

*.h文件會被放到地址 /usr/local/include/libxml2/libxmlxml

*.so文件會被放到地址 /usr/local/lib資源

2、源碼一(a.cpp)

a.cpp創建了一個XML文檔,根節點List,下面有2個Person,每一個Person下有若干屬性和若干Achievement做爲子結點

#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;
}

3、源碼二(b.cpp)

b.cpp對a.cpp中創建的XML文檔進行修改

#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;
}

4、編譯

在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

5、運行結果

END

相關文章
相關標籤/搜索