欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++利用libxml2高效輸出XML大文件詳解

 更新時(shí)間:2017年11月21日 11:57:48   作者:infoworld  
這篇文章主要給大家介紹了關(guān)于C/C++利用libxml2高效輸出XML大文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。

前言

Libxml2 是一個(gè)xml c語(yǔ)言版的解析器,本來是為Gnome項(xiàng)目開發(fā)的工具,是一個(gè)基于MIT License的免費(fèi)開源軟件。它除了支持c語(yǔ)言版以外,還支持c++、PHP、Pascal、Ruby、Tcl等語(yǔ)言的綁定,能在Windows、Linux、Solaris、MacOsX等平臺(tái)上運(yùn)行。功能還是相當(dāng)強(qiáng)大的,相信滿足一般用戶需求沒有任何問題。

libxml2常用數(shù)據(jù)類型

xmlChar是libxml2中的字符類型,在庫(kù)中的所有字符,字符串都是基于這個(gè)數(shù)據(jù)類型的。

xmlChar*是指針類型,很多函數(shù)都會(huì)返回一個(gè)動(dòng)態(tài)分配的內(nèi)存的xmlChar*類型的變量,因此,在使用這類函數(shù)時(shí)要記得釋放內(nèi)存,否則會(huì)導(dǎo)致內(nèi)存泄漏,例如這樣的用法:

xmlChar *name = xmlNodeGetContent(CurNode);
strcpy(data.name, name);
xmlFree(name);
  • xmlDoc、 xmlDocPtr //文檔對(duì)象結(jié)構(gòu)體及指針
  • xmlNode、 xmlNodePtr //節(jié)點(diǎn)對(duì)象結(jié)構(gòu)體及節(jié)點(diǎn)指針
  • xmlAttr、 xmlAttrPtr //節(jié)點(diǎn)屬性的結(jié)構(gòu)體及其指針
  • xmlNs、 xmlNsPtr //節(jié)點(diǎn)命名空間的結(jié)構(gòu)及指針
  • BAD_CAST //一個(gè)宏定義,事實(shí)上它即是xmlChar*類型

場(chǎng)景

1.libxml2基本上算是xml的C/C++標(biāo)準(zhǔn)讀寫庫(kù). 在linux,macOS里是默認(rèn)支持. 可惜在Windows上有自己專有的msxml, 所以并不支持libxml2, 惡心的是msxml還不是標(biāo)配, 還要必須另外下載安裝, 所以作為Windows上優(yōu)先選擇的XML庫(kù), 就是可跨平臺(tái)的libxml2.

2.xml的sax讀取庫(kù)expat也是比較優(yōu)秀的選擇, 可惜不支持寫.

3.一般的寫庫(kù)方式是生成一整個(gè)DOM結(jié)構(gòu), 之后把這個(gè)DOM結(jié)構(gòu)輸出到XML格式的文本里, 可調(diào)用自帶寫函數(shù)或標(biāo)準(zhǔn)io函數(shù). 這樣的缺點(diǎn)是如果生成這個(gè)DOM結(jié)構(gòu)過于大, 會(huì)導(dǎo)致在生成這個(gè)DOM結(jié)構(gòu)時(shí)內(nèi)存暴漲,之后再輸出到內(nèi)存里,這時(shí)候內(nèi)存又暴漲一次,最后從內(nèi)存輸出到文件里.

說明

1.DOM結(jié)構(gòu)存儲(chǔ)非常浪費(fèi)內(nèi)存, 如果數(shù)據(jù)量大時(shí), 但是元素的父子關(guān)系, 文本值,屬性值等等很浪費(fèi)內(nèi)存. 如果我們可以按照每個(gè)元素來輸出的話,最好輸出完就釋放元素內(nèi)存, 那么能最大限度的利用內(nèi)存資源.

2.局部輸出元素可以最大限度使用系統(tǒng)的資源, 比如IO輸出需要權(quán)限限制的函數(shù), 或者輸出到界面等

例子

以下例子是windows上使用libxml2, 用mingw編譯出的libxml2, 使用_wfopen來打開unicode編碼的文件路徑.

#include "stdafx.h"
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlreader.h>
#include <iostream>
#include <memory>

void TestStandardIOForXml()
{
 xmlDocPtr doc = NULL; /* document pointer */
 xmlNodePtr one_node = NULL, node = NULL, node1 = NULL;/* node pointers */
 char buff[256];
 int i, j;

 doc = xmlNewDoc(BAD_CAST "1.0");
 std::shared_ptr<void> sp_doc(doc,[](void* doc1){
 xmlDocPtr doc = (xmlDocPtr)doc1;
 xmlFreeDoc(doc);
 });

 FILE* file = _wfopen(L"test.xml",L"wb");
 if(!file)
 return;

 std::shared_ptr<FILE> sp_file(file,[](FILE* file){
 fclose(file);
 });

 // 寫XML的聲明
 xmlChar* doc_buf = NULL;
 int size = 0;
 xmlDocDumpMemoryEnc(doc,&doc_buf,&size,"UTF-8");
 std::shared_ptr<xmlChar> sp_xc(doc_buf,[](xmlChar* doc_buf){
 xmlFree(doc_buf);
 });
 fwrite(doc_buf,strlen((const char*)doc_buf),1,file);
 xmlBufferPtr buf = xmlBufferCreate();
 std::shared_ptr<void> sp_buf(buf,[](void* buf1){
 xmlBufferPtr buf = (xmlBufferPtr)buf1;
 xmlBufferFree(buf);
 });

 const char* kRootBegin = "<ROOT>";
 fwrite(kRootBegin,strlen(kRootBegin),1,file);
 for(int i = 0; i< 10; ++i){
 one_node = xmlNewNode(NULL, BAD_CAST "one");
 xmlNewChild(one_node, NULL, BAD_CAST "node1",
  BAD_CAST "content of node 1");
 xmlNewChild(one_node, NULL, BAD_CAST "node2", NULL);
 node = xmlNewChild(one_node, NULL, BAD_CAST "node3",BAD_CAST "this node has attributes");
 xmlNewProp(node, BAD_CAST "attribute", BAD_CAST "yes");
 xmlNewProp(node, BAD_CAST "foo", BAD_CAST "bar");

 node = xmlNewNode(NULL, BAD_CAST "node4");
 node1 = xmlNewText(BAD_CAST "other way to create content (which is also a node)");
 xmlAddChild(node, node1);
 xmlAddChild(one_node, node);

 xmlNodeDump(buf,doc,one_node,1,1);
 fwrite(buf->content,buf->use,1,file);

 xmlUnlinkNode(one_node);
 xmlFreeNode(one_node);
 xmlBufferEmpty(buf);
 }

 const char* kRootEnd = "</ROOT>";
 fwrite(kRootEnd,strlen(kRootEnd),1,file);

}

輸出文件:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT><one>
 <node1>contentÖÐÎÄ of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one><one>
 <node1>content of node 1</node1>
 <node2/>
 <node3 attribute="yes" foo="bar">this node has attributes</node3>
 <node4>other way to create content (which is also a node)</node4>
 </one></ROOT>

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • C++入門筆記之std::vector容器詳解

    C++入門筆記之std::vector容器詳解

    這篇文章主要給大家介紹了關(guān)于C++之std::vector容器的相關(guān)資料,vector,一種隨機(jī)訪問的數(shù)組類型,它提供了對(duì)數(shù)組元素的快速、隨機(jī)訪問,以及在序列尾部快速、隨機(jī)的插入和刪除操作,需要的朋友可以參考下
    2021-07-07
  • C 語(yǔ)言條件運(yùn)算符詳細(xì)講解

    C 語(yǔ)言條件運(yùn)算符詳細(xì)講解

    本文主要介紹C語(yǔ)言中的條件運(yùn)算符,并提供示例代碼以便大家學(xué)習(xí)參考,希望能幫助學(xué)習(xí) C語(yǔ)言的同學(xué)
    2016-07-07
  • C++ std::function詳解

    C++ std::function詳解

    類模版std::function是一種通用的多態(tài)函數(shù)包裝器std::function的實(shí)例可以對(duì)任何可以調(diào)用的目標(biāo)實(shí)體進(jìn)行存儲(chǔ)、復(fù)制、和調(diào)用操作,本文詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-10-10
  • C++中的類型查詢之探索typeid和type_info(推薦)

    C++中的類型查詢之探索typeid和type_info(推薦)

    C++ 是一種靜態(tài)類型語(yǔ)言,這意味著每個(gè)變量的類型在編譯時(shí)就已經(jīng)確定,在這篇技術(shù)分享中,我們將探討 C++ 中的 typeid 和 type_info,以及如何使用它們來獲取類型信息,需要的朋友可以參考下
    2024-05-05
  • 如何在C++中實(shí)現(xiàn)按位存取

    如何在C++中實(shí)現(xiàn)按位存取

    實(shí)現(xiàn)緊湊存取,不是按一個(gè)字節(jié)一個(gè)字節(jié)地存取,而是按位存取,本文就是介紹了如何在C++中實(shí)現(xiàn)按位存取,需要的朋友可以參考下
    2015-07-07
  • 利用C語(yǔ)言繪制一個(gè)正方體

    利用C語(yǔ)言繪制一個(gè)正方體

    這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言繪制一個(gè)正方體,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)和借鑒價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-01-01
  • C++ lambda 捕獲模式與右值引用的使用

    C++ lambda 捕獲模式與右值引用的使用

    這篇文章主要介紹了C++ lambda 捕獲模式與右值引用的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • OpenCV實(shí)現(xiàn)圖像細(xì)化算法

    OpenCV實(shí)現(xiàn)圖像細(xì)化算法

    本文主要介紹了OpenCV實(shí)現(xiàn)圖像細(xì)化算法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • C++實(shí)現(xiàn)defer聲明方法詳解

    C++實(shí)現(xiàn)defer聲明方法詳解

    這篇文章主要介紹了C++實(shí)現(xiàn)defer聲明,在和朋友交談時(shí)候,無(wú)意間了解到Go語(yǔ)言的defer,發(fā)現(xiàn)挺有意思的。和智能指針類似,當(dāng)出了作用域后,被defer修飾的操作才會(huì)執(zhí)行
    2022-11-11
  • C/C++的各種字符串函數(shù)你知道幾個(gè)

    C/C++的各種字符串函數(shù)你知道幾個(gè)

    這篇文章主要為大家詳細(xì)介紹了C/C++的各種字符串函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評(píng)論