欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
C 中的XML配置文件編程經(jīng)驗
 

C++中并沒(méi)有操作XML文件的標準庫,因此大家需要使用各自熟悉的XML庫來(lái)解決XML文件的讀取與寫(xiě)入。XML的一個(gè)重要用途是作為程序的配置文件,存儲程序運行相關(guān)的各種數據。本文總結了使用libxml2庫來(lái)對XML配置文件進(jìn)行編程的一些經(jīng)驗。最后提供了一個(gè)封裝好的類(lèi)CXMLConfig,并詳細說(shuō)明了該類(lèi)的功能、使用方法和注意事項。

閱讀本文所需的技術(shù)背景:

l         C/C++簡(jiǎn)單語(yǔ)法;

l         XML技術(shù),XPATH技術(shù);

l         C++編譯器知識;

本文的內容包括:

l         下載與安裝LIBXML2ICONV;

l         第一個(gè)例子程序的編寫(xiě)、編譯鏈接和運行;

l         使用XPATH讀出多個(gè)配置項的值;

l         XML的配置文件類(lèi)CXMLConfig;

l         將配置項寫(xiě)入XML文件;

l         CXMLConfig類(lèi)使用小結;

閱讀本文之前最好先讀我的上一篇博客C++XML編程經(jīng)驗――LIBXML2庫使用指南,那一篇專(zhuān)門(mén)介紹libxml2庫的使用方法。本文將不會(huì )再詳細介紹libxml2的使用,而是集中精力介紹如何存取XML中的數據。

本文的源代碼是一個(gè)VC6的工程,里面包含三個(gè)子工程。地址在http://www.blogjava.net/Files/wxb_nudt/XMLConfigFile.rar。

1.       下載與安裝LIBXML2ICONV

為了方便讀者,這一段原文照抄上一篇博客。

Libxml2是一個(gè)C語(yǔ)言的XML程序庫,可以簡(jiǎn)單方便的提供對XML文檔的各種操作,并且支持XPATH查詢(xún),以及部分的支持XSLT轉換等功能。Libxml2的下載地址是http://xmlsoft.org/,完全版的庫是開(kāi)源的,并且帶有例子程序和說(shuō)明文檔。最好將這個(gè)庫先下載下來(lái),因為這樣可以查看其中的文檔和例子。

windows版本的的下載地址是http://www.zlatkovic.com/libxml.en.html;這個(gè)版本只提供了頭文件、庫文件和dll,不包含源代碼、例子程序和文檔。在文本中,只需要下載libxml2庫、iconv庫和zlib庫就行了(注意,libxml2庫依賴(lài)iconvzlib庫,本文中重點(diǎn)關(guān)注libxml2iconv,zlib不介紹),我使用的版本是libxml2-2.6.30.win32.zip、zlib-1.2.3.win32.zipiconv-1.9.2.win32.zip。

在編程的時(shí)候,我們使用windows版本的libxml2、zlibiconv,將其解壓縮到指定文件夾,例如D:"libxml2-2.6.30.win32,D:"zlib-1.2.3.win32以及D:"iconv-1.9.2.win32。事實(shí)上,我們知道在windows下面使用頭文件、庫文件和dll是不需要安裝的,它又沒(méi)有使用任何需要注冊的組件或者數據庫,只需要告訴編譯器和鏈接器這些資源的位置就可以了。

注意:要在path變量中加上D:"iconv-1.9.2.win32"bin;D:"zlib-1.2.3.win32"bin;D:"libxml2-2.6.30.win32"bin這三個(gè)地址,否則在執行的時(shí)候就找不到?;蛘呤褂酶?jiǎn)單的方法,把其中的三個(gè)dll到拷貝到system32目錄中。

有兩種方法來(lái)編譯鏈接基于libxml2的程序,第一種是在VC環(huán)境中設置libinclude路徑,并在link設置中添加libxml2.libiconv.lib;第二種是用編譯器選項告訴編譯器cl.exe頭文件的位置,并用鏈接器選項告訴鏈接器link.exe庫文件的位置,同時(shí)在windows環(huán)境變量path中添加libxml2bin文件夾的位置,以便于程序運行時(shí)可以找到dll(也可以將dll拷貝到system32目錄下)。

2.       HELLO,XML CONFIG FILE

本節的源代碼位于項目HelloXml中,使用的xml文件是Helloxml.xml。

在安裝配置好libxml2iconv庫之后,就可以寫(xiě)一個(gè)簡(jiǎn)單的程序來(lái)讀取XML中的數據了。該XML內容如下:

 <?xml version="1.0" encoding="GB2312" ?>

 <main>20080526</main>

使用libxml2庫讀取main節點(diǎn)包含的內容,代碼如下:

xmlChar* LoadConfigFile(const char* szConfigFilename, xmlChar* xszRel)

{

    xmlDocPtr doc;   //定義解析文檔指針

    xmlNodePtr curNodePtr; //定義結點(diǎn)指針

    doc = xmlReadFile(szConfigFilename,"GB2312",XML_PARSE_RECOVER); //解析文件

    if (doc == NULL )

    {

       fprintf(stderr,"Document not parsed successfully. "n");    

       xmlFreeDoc(doc);

       exit(1);

    }  

    curNodePtr = xmlDocGetRootElement(doc); //確定文檔根元素

    /*檢查確認當前文檔中包含內容*/

    if (curNodePtr == NULL)

    {

       fprintf(stderr,"empty document"n");

       xmlFreeDoc(doc);

       exit(1);

    }

    //讀取xml文檔中的內容并賦值給對象屬性

    xszRel = xmlNodeGetContent(curNodePtr);

    xmlFreeDoc(doc);

    return xszRel;

}

int main(int argc, char* argv[])

{

    xmlChar* xszContent = NULL;

    xszContent = LoadConfigFile("..""Debug""HelloXml.xml",xszContent);

    if (xszContent != NULL)

    {

       cout<<"HELLO, XML CONFIG FILE. content = "<<xszContent<<endl;

       xmlFree(xszContent);

    }

    return 0;

}

編譯代碼之前要注意:xml文檔存放的地點(diǎn)不是本項目文件夾,而是項目文件夾上層的Debug目錄,同時(shí)將編譯和鏈接的目的文件夾都設置為項目文件夾上層的Debug目錄。第二點(diǎn),在link選項中加入了libxml2.libiconv.lib。第三點(diǎn),在系統的Path變量中指明了libxml2.dll、iconv.dllzlib1.dll的路徑(為了方便讀者,我將這三個(gè)dll都拷貝到了Debug目錄下面)。

編譯鏈接完畢后運行程序,得到如下結果:

HELLO, XML CONFIG FILE. content = 20080526

3.       使用XPATH讀出多個(gè)配置項的值

本節的源代碼位于項目XPathConfig中,使用的xml文件是XPathConfig.xml。

上面的例子中,為了理解的便利僅在根節點(diǎn)中存儲了一個(gè)值,而實(shí)際的配置文件往往是同時(shí)存放多個(gè)配置項的值。舉例如下:

<main>

    <IP>127.0.0.1</IP>

    <Port>80</Port>

</main>

Xml中存儲了一個(gè)IP地址和一個(gè)端口值。其XPATH地址分別是/main/IP//main/Port/。當然,更加復雜的XPATH值也可同樣處理。

為了方便的操作xml文檔,我寫(xiě)了一組xml函數,位于Code_Conv.hCode_Conv.cpp中,其功能如下:

l         openXmlFile,打開(kāi)Xml文檔,返回文檔指針;

l         closeXmlFile,關(guān)閉Xml文檔;

l         getXmlString,根據XPATH路徑讀取字符串;

l         getXmlInt,根據XPATH路徑讀取整型值;

為了處理中文以及查詢(xún)Xpath節點(diǎn),我還寫(xiě)了四個(gè)被上述函數調用的函數:

l         code_convert,從一種編碼轉為另一種編碼;

l         u2g,從UTF-8轉換為GB2312編碼;

l         g2u,從GB2312轉換為UTF-8編碼;

l         get_nodeset,調用xpath查詢(xún)節點(diǎn)集合,成功則返回xpath的對象指針,失敗返回NULL。

然后,主程序便簡(jiǎn)化為:

int main(int argc, char* argv[])

{

    xmlDocPtr doc = openXmlFile("..""Debug""XPathConfig.xml");

    string strIP = getXmlString(doc,"/main/IP");

    int iPort = getXmlInt(doc,"/main/Port");

    cout<<"IP = "<<strIP.c_str()<<" Port = "<<iPort<<endl;

    closeXmlFile(doc);

    return 0;

}

運行結果為:

IP = 127.0.0.1 Port = 80

觀(guān)察上面的代碼可以發(fā)現,整個(gè)主程序幾乎與libxml2庫無(wú)關(guān)了,除了一個(gè)xmlDocPtr變量。再次觀(guān)察可以發(fā)現,這個(gè)變量幾乎出現在每個(gè)自定義函數中,它代表的是一種狀態(tài),或者可以稱(chēng)為屬性。而那些自定義函數可以稱(chēng)之為功能。因此,按照許多C++專(zhuān)著(zhù)的說(shuō)法,屬性+功能=對象?!?/span>C++沉思錄》中說(shuō)道,CC++最大的不同在于,C++擁有一個(gè)最合適的存儲程序狀態(tài)的位置,即對象的屬性;而C則必須在許多函數中留出一個(gè)位置來(lái)保存這個(gè)狀態(tài)。這句話(huà),簡(jiǎn)直正確得可怕!

4.       XML的配置文件類(lèi)CXMLConfig

本節的源代碼位于項目UseClass中,使用的xml文件還是XPathConfig.xml。

于是有了下面的CXMLConfig類(lèi)定義:

class CXMLConfig 

{

public:

    CXMLConfig(const char* szXmlFilename);

    ~CXMLConfig();

    //根據XPATH路徑讀取字符串

    string getXmlString(const char *szXpath);

    int getXmlInt(const char* szXpath);   

private:

    //代碼轉換:從一種編碼轉為另一種編碼  

    int code_convert(char* from_charset, char* to_charset, char* inbuf,int inlen, char* outbuf, int outlen);

    //UNICODE碼轉為GB2312碼  

    //成功則返回一個(gè)動(dòng)態(tài)分配的char*變量,需要在使用完畢后手動(dòng)free,失敗返回NULL

    char* u2g(char *inbuf);

    //GB2312轉為UNICODE   

    //成功則返回一個(gè)動(dòng)態(tài)分配的char*變量,需要在使用完畢后手動(dòng)free,失敗返回NULL

    char* g2u(char *inbuf);

    //調用xpath查詢(xún)節點(diǎn)集合,成功則返回xpath的對象指針,失敗返回NULL

    xmlXPathObjectPtr get_nodeset(const xmlChar *xpath);

private:

    string m_strFilename;

    xmlDocPtr m_doc;

};

使用這個(gè)類(lèi)來(lái)改寫(xiě)主程序,可以讓使用者完全脫離libxml2的庫環(huán)境,并且省略了打開(kāi)和關(guān)閉xml文件的步驟,因為這些工作在構造和析構函數中完成了。

int main(int argc, char* argv[])

{

    CXMLConfig xmlConfig("..""Debug""XPathConfig.xml");

    string strIP = xmlConfig.getXmlString("/main/IP");

    int iPort = xmlConfig.getXmlInt("/main/Port");

    cout<<"IP = "<<strIP.c_str()<<" Port = "<<iPort<<endl;

    return 0;

}

運行結果為:

IP = 127.0.0.1 Port = 80

5.       將配置項寫(xiě)入XML文件

本節的源代碼位于項目UseClass中,使用的xml文件依然是XPathConfig.xml。

目前CXMLConfig類(lèi)已經(jīng)有了打開(kāi)xml文件,讀取數據以及關(guān)閉xml文件的功能。還缺少寫(xiě)入數據的功能。寫(xiě)入數據功能的算法也很簡(jiǎn)單:先將xml文件讀入內存,然后通過(guò)xpath找到相應節點(diǎn),并修改節點(diǎn)內容,最后將內存中的xml文件一次性寫(xiě)入硬盤(pán)。這里有一點(diǎn)要注意,如果在寫(xiě)入過(guò)程中硬盤(pán)斷電或者出現其他故障,則會(huì )造成無(wú)法恢復的錯誤,數據會(huì )全部丟失。為了防止這種情況,還應該在寫(xiě)入前進(jìn)行數據備份的工作。通盤(pán)考慮后,在CXMLConfig類(lèi)中加入如下函數:

writeXmlString:將字符串寫(xiě)入xml文檔相應節點(diǎn);

writeXmlInt:將整型寫(xiě)入xml文檔相應節點(diǎn);

saveConfigFile:將內存中的xml文檔寫(xiě)入硬盤(pán);

saveBakConfigFile:保存當前的xml文檔到bak文件(即xml文檔名加_BAK.XML)中;

loadBakConfigFile:將bak文件讀入內存;

注意,在調用saveConfigFile時(shí)會(huì )自動(dòng)調用saveBakConfigFile,將原有配置文件保存為備份文件。修改后的類(lèi)如下:

class CXMLConfig 

{

public:

    CXMLConfig(const char* szXmlFilename);

    ~CXMLConfig();

    //根據XPATH路徑讀取字符串

    string getXmlString(const char *szXpath);

    int getXmlInt(const char* szXpath);   

    bool writeXmlString(const string strValue, const char* szXpath);

    bool writeXmlInt(const int iValue, const char* szXpath);

    bool saveConfigFile();

    bool saveBakConfigFile();

    bool loadBakConfigFile();

private:

    //代碼轉換:從一種編碼轉為另一種編碼  

    int code_convert(char* from_charset, char* to_charset, char* inbuf,

                   int inlen, char* outbuf, int outlen);

    //UNICODE碼轉為GB2312碼  

    char* u2g(char *inbuf);

    //GB2312轉為UNICODE  

    char* g2u(char *inbuf);

    //調用xpath查詢(xún)節點(diǎn)集合,成功則返回xpath的對象指針,失敗返回NULL

    xmlXPathObjectPtr get_nodeset(const xmlChar *xpath);

    // 禁止拷貝構造函數和"="操作

    CXMLConfig(const CXMLConfig&);

    CXMLConfig& operator=(const CXMLConfig&);

private:

    string m_strFilename;

    xmlDocPtr m_doc;

};

然后我們修改了主程序,其功能為讀出數據后修改了數據,然后存入了配置文件,主程序如下:

int main(int argc, char* argv[])

{

    CXMLConfig xmlConfig("..""Debug""XPathConfig.xml");

    string strIP = xmlConfig.getXmlString("/main/IP");

    int iPort = xmlConfig.getXmlInt("/main/Port");

    cout<<"IP = "<<strIP.c_str()<<" Port = "<<iPort<<endl;

    strIP = "127.1.1.1";

    iPort = 81;

    xmlConfig.writeXmlString(strIP,"/main/IP");

    xmlConfig.writeXmlInt(iPort,"/main/Port");

    if(xmlConfig.saveConfigFile())

    {

       cout<<"Save Config file success!"<<endl;

    }

    return 0;

}

運行完以后會(huì )發(fā)現兩個(gè)結果,第一個(gè)是配置文件XPathConfig.xml中的內容已經(jīng)被修改,第二個(gè)是原配置文件內容備份在XPathConfig_bak.xml中。

6.       CXMLConfig類(lèi)使用小結

目前為止,CXMLConfig類(lèi)提供了較為便利的讀取和保存XML配置文件的功能。那么使用CXMLConfig需要哪些步驟呢?

第一,正確安裝了libxml2iconv庫,包括頭文件、lib文件和dll文件。注意頭文件主要是libxml2iconv的頭文件,lib文件就是兩個(gè)libxml2.libiconv.lib,而dll有三個(gè),即libxml2.dll、iconv.dllzlib1.dll。注意:如果你沒(méi)有正確安裝,那么無(wú)法正確編譯我的例子程序,但是可以運行,因為我已經(jīng)將dll都包含到運行目錄下。

第二,確信你弄懂了你的xml配置文件結構,并放在正確的地方;

第三,使用CXMLConfig xmlConfig("..""Debug""XPathConfig.xml")語(yǔ)句正確構造一個(gè)CXMLConfig對象,并調用相應的方法來(lái)操作xml文件。

CXMLConfig類(lèi)使用的注意事項:

第一,注意xml文件必須使用節點(diǎn)來(lái)存儲數據,而不是屬性。若使用屬性來(lái)保存數據,CXMLConfig類(lèi)不會(huì )正確讀出其數據,當然更不能正確寫(xiě)入。若有興趣,可以擴展CXMLConfig類(lèi)來(lái)實(shí)現對屬性數據的存取,事實(shí)上那非常簡(jiǎn)單。

第二,若有兩個(gè)節點(diǎn)的XPATH路徑相同,例如

<main>

    <IP>127.0.0.1</IP>

<IP>127.0.0.2</IP>

    <Port>80</Port>

</main>

那么使用getXmlString將只會(huì )得到第一個(gè)節點(diǎn)的內容。同理,寫(xiě)入時(shí)也只會(huì )寫(xiě)入第一個(gè)節點(diǎn)。

CXMLConfig類(lèi)的使用環(huán)境:

第一,   使用節點(diǎn)來(lái)存儲數據;

第二,   節點(diǎn)的XPATH路徑各不相同;

第三,   XML文件最好不大于100M。

總之,若有更復雜的要求,請還是仔細研究libxml2或者任意一個(gè)開(kāi)源或商用XML庫。

7.       文末的話(huà)

事實(shí)上,按照原計劃這篇博客才剛剛開(kāi)頭,后面才是最精彩的部分。其內容是介紹如何將XML文件當作一個(gè)小型的數據庫,把多個(gè)XPATH路徑相同的鍵和值讀入一個(gè)std::map<std::string,std::string>中,然后在程序中方便的使用這個(gè)map來(lái)查找,存取某一類(lèi)數據。但是由于前面的部分寫(xiě)作時(shí)考慮得太詳細,而且CXMLConfig類(lèi)也介紹逐漸趨于完善,因此為了防止喧賓奪主,本文就到這里結束為好。作為一篇libxml2C++的入門(mén)文章,恰到好處!

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C 的XML編程經(jīng)驗――LIBXML2庫使用指南
XML常見(jiàn)的操作
解決libxml2不支持中文的問(wèn)題
linux下xml解析-使用libxml2實(shí)現對xml文件的讀取及查詢(xún)
把lua嵌入到c++中當讀配置文件
Windows環(huán)境下libxml2庫的使用小結
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久