linux高并發(fā)網(wǎng)絡(luò)編程開發(fā)-課件10系統(tǒng)第16天json1教學(xué)minixml中文_第1頁
linux高并發(fā)網(wǎng)絡(luò)編程開發(fā)-課件10系統(tǒng)第16天json1教學(xué)minixml中文_第2頁
linux高并發(fā)網(wǎng)絡(luò)編程開發(fā)-課件10系統(tǒng)第16天json1教學(xué)minixml中文_第3頁
linux高并發(fā)網(wǎng)絡(luò)編程開發(fā)-課件10系統(tǒng)第16天json1教學(xué)minixml中文_第4頁
linux高并發(fā)網(wǎng)絡(luò)編程開發(fā)-課件10系統(tǒng)第16天json1教學(xué)minixml中文_第5頁
免費預(yù)覽已結(jié)束,剩余50頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

北京市昌平區(qū)建材城西路金燕龍辦公樓一層電話:400-618-9090Mini-XML入門這一章描述了如何寫一個程序使用Mini-XML來訪問XML文件中的數(shù)據(jù).Mini-XML提供了以下功能:在內(nèi)存中創(chuàng)建和管理XML文檔的函數(shù).讀UTF-8和UTF-16編碼的XML文件和字符串.寫UTF-8編碼的XML文件和字符串.支持任意的元素名稱,屬性以及屬性值,沒有任何其他限制,僅受限于有效內(nèi)存.支持整形、浮點、自定義("CDATA")和文本數(shù)據(jù)類型在"葉"節(jié)點.提供"查找"、"索引"、以及"步進(jìn)"函數(shù)可以很簡單的訪問XML文檔中的數(shù)據(jù).Mini-XML不進(jìn)行基于"XML方案(SCHEMA)"文件或者其他內(nèi)容源定義信息的校驗和其他類型的處理,也不支持其他組織所要求的XML規(guī)范.基礎(chǔ)知識Mini-XML提供的一個你需要包含的頭文件:#include<mxml.h>把Mini-XML庫連接到你的應(yīng)用程序使用-lmxml選項:gcc-omyprogrammyprogram.c-lmxmlENTER如果你已經(jīng)安裝pkg-config(1)軟件,你可以使用它來為你的安裝確定適當(dāng)?shù)木幾g和連接選項:pkg-config--cflagsmxmlENTERpkg-config--libsmxmlENTER節(jié)點每一塊XML文件中的信息片斷(元素、文本、數(shù)字)是一個存儲在內(nèi)存中的"節(jié)點(nodes)".節(jié)點使用mxml_node_t結(jié)構(gòu)進(jìn)行定義.它的type成員變量定義了節(jié)點類型(element,integer,opaque,real,ortext)決定了需要從聯(lián)合(union)類型的成員變量value中獲取的值.表2-1:Mini-XML節(jié)點值的成員變量值類型節(jié)點成員用戶定義void*node->value.custom.dataXML元素char*node->整數(shù)intnode->eger不透明字符串char*node->value.opaque浮點數(shù)doublenode->value.real文本char*node->value.text.string譯者:節(jié)點類型定義枚舉參見:mxml_type_e。Mini-XML中的節(jié)點類型定義和其他有些解析器有些不同,其中整數(shù)、浮點、和文本節(jié)點是指在一個XML元素中一系列的使用空格作為分割的值,每個元素可以擁有多個以上節(jié)點,并可以選擇使用空格分開,如:<abc>aabbcc</abc>,Mini-MXML在使用參數(shù):MXML_TEXT_CALLBACK進(jìn)行載入時,將在abc元素下面生成3個text類型的子節(jié)點。在創(chuàng)建時也可以使用同樣的方式創(chuàng)建節(jié)點。整數(shù)和浮點也是同樣方式,但如果轉(zhuǎn)換失敗則MiniXML報錯。而不透明字符串類型(OPAQUE)則不進(jìn)行字符串分割,在載入時需要使用MXML_OPAQUE_CALLBACK參數(shù),將所有字符串形成一個子節(jié)點。詳情見:使用加載回調(diào)函數(shù)。Z.F每一個節(jié)點總是有一個成員變量:user_data可以允許你為每一個節(jié)點關(guān)聯(lián)你需要的應(yīng)用數(shù)據(jù).新的節(jié)點可以使用以下函數(shù)進(jìn)行創(chuàng)建mxmlNewElement,mxmlNewInteger,mxmlNewOpaque,mxmlNewReal,mxmlNewTextmxmlNewTextfmxmlNewXML.只有elements可以擁有子節(jié)點,頂級節(jié)點必須是一個element,通常是<?xmlversion="1.0"?>使用mxmlNewXML()函數(shù)創(chuàng)建的節(jié)點.每個節(jié)點都有一些關(guān)聯(lián)節(jié)點的指針,上(parent),下(child),左(prev),and右(next)相對應(yīng)于當(dāng)前節(jié)點.如果你有一個XML文件如下所示:<?xmlversion="1.0"?><data><node>val1</node><node>val2</node><node>val3</node><group><node>val4</node><node>val5</node><node>val6</node></group><node>val7</node><node>val8</node></data>那么在內(nèi)存中的文件節(jié)點樹看上去如下所示:?xml|data|node-node-node-group-node-node||||||val1val2val3|val7val8|node-node-node|||val4val5val6這里"-"指向下一個節(jié)點,"|"指向第一個子節(jié)點。當(dāng)你使用完畢這些XML數(shù)據(jù)后,使用函數(shù)mxmlDelete來釋放指定節(jié)點或者整個XML樹節(jié)點和它下面所有子節(jié)點的內(nèi)存:mxmlDelete(tree);創(chuàng)建XML文檔你可以在內(nèi)存中創(chuàng)建和更新XML文檔,使用mxmlNew一系列函數(shù).下面的代碼將創(chuàng)建上一章描述的XML文檔:mxml_node_t*xml;/*<?xml...?>*/mxml_node_t*data;/*<data>*/mxml_node_t*node;/*<node>*/mxml_node_t*group;/*<group>*/xml=mxmlNewXML("1.0");data=mxmlNewElement(xml,"data");node=mxmlNewElement(data,"node");mxmlNewText(node,0,"val1");node=mxmlNewElement(data,"node");mxmlNewText(node,0,"val2");node=mxmlNewElement(data,"node");mxmlNewText(node,0,"val3");group=mxmlNewElement(data,"group");node=mxmlNewElement(group,"node");mxmlNewText(node,0,"val4");node=mxmlNewElement(group,"node");mxmlNewText(node,0,"val5");node=mxmlNewElement(group,"node");mxmlNewText(node,0,"val6");node=mxmlNewElement(data,"node");mxmlNewText(node,0,"val7");node=mxmlNewElement(data,"node");mxmlNewText(node,0,"val8");我們首先使用mxmlNewXML函數(shù)來創(chuàng)建所有XML文件都需要的標(biāo)頭<?xmlversion="1.0"?>:xml=mxmlNewXML("1.0");然后我們使用mxmlNewElement函數(shù)來創(chuàng)建本文件使用的<data>節(jié)點.第一個參數(shù)指定了父節(jié)點(xml),第二個參數(shù)是元素名(data):data=mxmlNewElement(xml,"data");每個在本文件中<node>...</node>之間的部分使用函數(shù)mxmlNewElement和mxmlNewText來創(chuàng)建.mxmlNewText的第一個參數(shù)指定了父節(jié)點(node).第二個參數(shù)指定了是否在文本之前添加空白字符,在本例中使用0或者false.最后一個參數(shù)指定了需要添加的實際文本:node=mxmlNewElement(data,"node");mxmlNewText(node,0,"val1");在內(nèi)存中的XML結(jié)果可以被保存或者進(jìn)行其他處理,就像一個從磁盤或者字符串中讀取的文檔一樣.加載XML你可以加載一個XML文件使用函數(shù)mxmlLoadFile:FILE*fp;mxml_node_t*tree;fp=fopen("filename.xml","r");tree=mxmlLoadFile(NULL,fp,MXML_TEXT_CALLBACK);fclose(fp);第一個參數(shù)如果有的話則指定了一個存在的XML父節(jié)點.一般你將這個參數(shù)等于NULL,除非你想要連接多個XML源.如果此參數(shù)等于NULL,那么指定的XML文件必須是一個完整的XML文檔,文檔頭部要包含?xml元素.第二個參數(shù)指定了一個標(biāo)準(zhǔn)的文件流,使用fopen()或者popen()進(jìn)行打開.你也可以使用stdin,如果你想要實現(xiàn)一個XML過濾器程序.第三個參數(shù)指定了一個回調(diào)函數(shù)用于一個新的XML元素節(jié)點直接返回的子節(jié)點的值類型:MXML_CUSTOM,MXML_IGNORE,MXML_INTEGER,MXML_OPAQUE,MXML_REAL,orMXML_TEXT.加載回調(diào)函數(shù)的細(xì)節(jié)在第三章做了詳細(xì)描述.示例代碼使用MXML_TEXT_CALLBACK常量指定文檔中所有的數(shù)據(jù)節(jié)點都包含使用以空格字符分割的文本的值.其他標(biāo)準(zhǔn)的回調(diào)還有MXML_IGNORE_CALLBACK,MXML_INTEGER_CALLBACK,MXML_OPAQUE_CALLBACK,和MXML_REAL_CALLBACK.函數(shù)mxmlLoadString可以從一個字符串中載入XML節(jié)點樹:charbuffer[8192];mxml_node_t*tree;...tree=mxmlLoadString(NULL,buffer,MXML_TEXT_CALLBACK);第一個和第三個參數(shù)和mxmlLoadFile()用法一樣.第二個參數(shù)指定了指定了字符串或者字符緩沖區(qū)用于加載XML,當(dāng)父節(jié)點參數(shù)為NULL時內(nèi)容必須為完整的XML文檔,包括XML頭?xml元素.保存XML你可以保存XML文件使用mxmlSaveFile函數(shù):FILE*fp;mxml_node_t*tree;fp=fopen("filename.xml","w");mxmlSaveFile(tree,fp,MXML_NO_CALLBACK);fclose(fp);第一個參數(shù)為想要保存的XML節(jié)點樹,一般應(yīng)該是一個指向你的XML文檔頂級節(jié)點?xml的節(jié)點指針.第二個單數(shù)是一個標(biāo)準(zhǔn)文件流,使用fopen()或者popen()來打開.你也可以使用stdout如果你想要實現(xiàn)一個XML過濾器程序.第三個參數(shù)是一個空白回調(diào)函數(shù)用來控制保存文件時插入的"空白"字符."空白回調(diào)"的詳細(xì)信息參見第三章.以上的示例代碼使用了MXML_NO_CALLBACK常量來指定不需要特別的空白處理.函數(shù)mxmlSaveAllocString,和mxmlSaveString保存XML節(jié)點樹到一個字符串中:charbuffer[8192];char*ptr;mxml_node_t*tree;...mxmlSaveString(tree,buffer,sizeof(buffer),MXML_NO_CALLBACK);...ptr=mxmlSaveAllocString(tree,MXML_NO_CALLBACK);第一個和最后一個參數(shù)的用法和函數(shù)mxmlSaveFile()一樣.函數(shù)mxmlSaveString給出了一個指針和長度的參數(shù)來保存XML文檔到一個固定大小的緩沖區(qū)中。,mxmlSaveAllocString()返回了使用malloc分配的一個字符串緩沖區(qū)malloc().自動折行控制當(dāng)我們保存XML文檔時,Mini-XML一般在第75列進(jìn)行折行,因為這樣在終端下最易讀.函數(shù)mxmlSetWrapMargin可以覆蓋缺省的折行界限:/*設(shè)置自動折行到132列*/mxmlSetWrapMargin(132);/*取消自動折行*/mxmlSetWrapMargin(0);搜索和遍歷節(jié)點函數(shù)mxmlWalkPrevandmxmlWalkNext可以被用來遍歷XML節(jié)點樹:mxml_node_t*node;node=mxmlWalkPrev(current,tree,MXML_DESCEND);node=mxmlWalkNext(current,tree,MXML_DESCEND);另外,你可以搜索一個命名的XML元素/節(jié)點,使用函數(shù)mxmlFindElement:mxml_node_t*node;node=mxmlFindElement(tree,tree,"name","attr","value",MXML_DESCEND);參數(shù)name,attr,和value可以被設(shè)置為NULL作為全部匹配,e.g.:/*搜索第一個"a"元素*/node=mxmlFindElement(tree,tree,"a",NULL,NULL,MXML_DESCEND);/*搜索第一個"a"元素并包含"href"屬性*/node=mxmlFindElement(tree,tree,"a","href",NULL,MXML_DESCEND);/*搜索第一個"a"元素并且包含"href"屬性等于給出的URL*/node=mxmlFindElement(tree,tree,"a","href","/",MXML_DESCEND);/*搜索第一個包含"src"屬性的XML元素*/node=mxmlFindElement(tree,tree,NULL,"src",NULL,MXML_DESCEND);/*搜索第一個包含"src"="foo.jpg"屬性的XML元素*/node=mxmlFindElement(tree,tree,NULL,"src","foo.jpg",MXML_DESCEND);你也可以使用同樣的功能進(jìn)行遍歷:mxml_node_t*node;for(node=mxmlFindElement(tree,tree,"name",NULL,NULL,MXML_DESCEND);node!=NULL;node=mxmlFindElement(node,tree,"name",NULL,NULL,MXML_DESCEND)){...dosomething...}參數(shù)MXML_DESCEND可以是下面三個常量之一:MXML_NO_DESCEND含義是不查看任何的子節(jié)點在XML元素層次中,僅查看同級的伙伴節(jié)點或者父節(jié)點直到到達(dá)頂級節(jié)點或者給出的樹的頂級節(jié)點."group"節(jié)點的上一個節(jié)點時它左面的"node"子節(jié)點,下一個節(jié)點是"group"右面的"node"子節(jié)點..

MXML_DESCEND_FIRST含義是向下搜索到一個節(jié)點的第一個匹配子節(jié)點,但不再繼續(xù)向下搜索。你一般使用于遍歷一個父節(jié)點的直接的子節(jié)點。,如:在上面的例子中的所有在"?xml"父節(jié)點下的所有的"node"和"group"子節(jié)點。.這個模式僅適用于搜索(search)功能,遍歷功能(walk)對待它和MXML_DESCEND一樣,因為每次調(diào)用都是首次調(diào)用。

MXML_DESCEND含義是一直向下直到樹的根部."group"節(jié)點的上一個節(jié)點將是"val3"節(jié)點,下一個節(jié)點將是"group"的下面的第一個子節(jié)點。如果你要使用函數(shù)mxmlWalkNext()從根結(jié)點"?xml"遍歷到整個樹的結(jié)束,那么這個順序?qū)⑷缦滤荆?xmldatanodeval1nodeval2nodeval3groupnodeval4nodeval5nodeval6nodeval7nodeval8如果你從"val8"開始并使用函數(shù)mxmlWalkPrev()進(jìn)行遍歷,這個順序?qū)⑹欠吹?,結(jié)束于"?xml"節(jié)點.更多的Mini-XML編程技術(shù)這一章顯示了更多的在你的應(yīng)用程序中使用Mini-XML的方法。LoadCallbacks第二章介紹了函數(shù)mxmlLoadFile()和mxmlLoadString().這些函數(shù)的最后一個參數(shù)是一個回調(diào)函數(shù),決定了在一個XML文檔中每個數(shù)據(jù)節(jié)點的值的類型。Mini-XML為簡單XML數(shù)據(jù)文件定義了幾個標(biāo)準(zhǔn)的回調(diào)函數(shù):MXML_INTEGER_CALLBACK-所有的數(shù)據(jù)節(jié)點包含以空格分割的整數(shù)。MXML_OPAQUE_CALLBACK-所有的數(shù)據(jù)節(jié)點包含"不透明"字符串(CDATA)。MXML_REAL_CALLBACK-所有的數(shù)據(jù)節(jié)點包含以空格分割的浮點數(shù)。MXML_TEXT_CALLBACK-所有的數(shù)據(jù)節(jié)點包含以空格分割的文本字符串。你可以為更復(fù)雜的XML文檔提供你自己的回調(diào)函數(shù)。你的回調(diào)函數(shù)將接收到一個到當(dāng)前XML元素節(jié)點的指針并且必須為這個XML元素節(jié)點返回一個直接子節(jié)點的值類型:MXML_INTEGER,MXML_OPAQUE,MXML_REAL,或MXML_TEXT.這個函數(shù)在這個XML元素和它的全部屬性被讀取以后被調(diào)用,所以你可以查看這個XML元素的名稱、屬性以及屬性的值來決定適當(dāng)?shù)姆祷刂殿愋?。下面的回調(diào)函數(shù)查看一個名稱為"type"的屬性或者XML元素的名字來決定它的子節(jié)點的值類型:mxml_type_ttype_cb(mxml_node_t*node){constchar*type;/**你可以查看屬性和/或使用XML元素名,所在層次,等等*/type=mxmlElementGetAttr(node,"type");if(type==NULL)type=node->;if(!strcmp(type,"integer"))return(MXML_INTEGER);elseif(!strcmp(type,"opaque"))return(MXML_OPAQUE);elseif(!strcmp(type,"real"))return(MXML_REAL);elsereturn(MXML_TEXT);}要使用這個回調(diào)函數(shù),只需要在你調(diào)用任何加載函數(shù)時簡單的使用它的名字:FILE*fp;mxml_node_t*tree;fp=fopen("filename.xml","r");tree=mxmlLoadFile(NULL,fp,type_cb);fclose(fp);保存回調(diào)第二章也介紹了mxmlSaveFile(),mxmlSaveString(),和mxmlSaveAllocString()函數(shù)。這些函數(shù)的最后一個參數(shù)是一個回調(diào)函數(shù)被用來自動在一個XML文檔中添加空白字符。你的回調(diào)函數(shù)將在每個XML元素被調(diào)用四次,傳入?yún)?shù)為一個到這個節(jié)點的指針和一個"where"的值:MXML_WS_BEFORE_OPEN,MXML_WS_AFTER_OPEN,MXML_WS_BEFORE_CLOSE,或者M(jìn)XML_WS_AFTER_CLOSE。如果不需要插入空白字符這個回調(diào)函數(shù)將返回NULL,否則返回字符串(空白、跳格、回車和換行)將被插入。下面的空白回調(diào)可以被用來為XHTML輸出添加空白字符,來使它在一般的文本編輯器中更加易讀:constchar*whitespace_cb(mxml_node_t*node,intwhere){constchar*name;/**我們可以在任何XML元素之前或之后有條件的添加換行。這些是一些常見的HTML元素。*/name=node->;if(!strcmp(name,"html")||!strcmp(name,"head")||!strcmp(name,"body")||!strcmp(name,"pre")||!strcmp(name,"p")||!strcmp(name,"h1")||!strcmp(name,"h2")||!strcmp(name,"h3")||!strcmp(name,"h4")||!strcmp(name,"h5")||!strcmp(name,"h6")){/**在打開之前和關(guān)閉之后時換行。*/if(where==MXML_WS_BEFORE_OPEN||where==MXML_WS_AFTER_CLOSE)return("\n");}elseif(!strcmp(name,"dl")||!strcmp(name,"ol")||!strcmp(name,"ul")){/**在列表元素前后都添加換行。*/return("\n");}elseif(!strcmp(name,"dd")||!strcmp(name,"dt")||!strcmp(name,"li")){/**添加一個"跳格"在<li>,*<dd>,*和<dt>之前,以及一個換行在他們后面...*/if(where==MXML_WS_BEFORE_OPEN)return("\t");elseif(where==MXML_WS_AFTER_CLOSE)return("\n");}/**如果不需要添加空白字符則返回NULL。*/return(NULL);}要使用這些回調(diào)函數(shù),只需要在你調(diào)用任何保存函數(shù)時簡單使用它的名字:FILE*fp;mxml_node_t*tree;fp=fopen("filename.xml","w");mxmlSaveFile(tree,fp,whitespace_cb);fclose(fp);用戶定義數(shù)據(jù)類型Mini-XML支持通過全局的載入和保存回調(diào)函數(shù)使用自定義數(shù)據(jù)類型。每次只能有一組回調(diào)函數(shù)被同時激活,然而你的回調(diào)函數(shù)可以為支持多種所需要的自定義數(shù)據(jù)類型來保存更多的信息。節(jié)點類型MXML_CUSTOM表示一個自定義數(shù)據(jù)內(nèi)容的節(jié)點。加載回調(diào)接收一個到當(dāng)前數(shù)據(jù)節(jié)點的指針和一個不透明字符串?dāng)?shù)據(jù)從XML源中并且將字符集轉(zhuǎn)換為UTF-8編碼。例如:如果我們想要支持定制的日期/時間類型并且編碼為"yyyy-mm-ddThh:mm:ssZ"(ISO格式),那么加載回調(diào)函數(shù)如下所示:typedefstruct{unsignedyear,/*Year*/month,/*Month*/day,/*Day*/hour,/*Hour*/minute,/*Minute*/second;/*Second*/time_tunix;/*UNIXtime*/}iso_date_time_t;intload_custom(mxml_node_t*node,constchar*data){iso_date_time_t*dt;structtmtmdata;/**分配數(shù)據(jù)結(jié)構(gòu)...*/dt=calloc(1,sizeof(iso_date_time_t));/**嘗試從數(shù)據(jù)字符串中讀取6個無符號整數(shù)..*/if(sscanf(data,"%u-%u-%uT%u:%u:%uZ",&(dt->year),&(dt->month),&(dt->day),&(dt->hour),&(dt->minute),&(dt->second))!=6){/**如果不能讀取到數(shù)字,釋放分配的結(jié)構(gòu)并返回一個錯誤...*/free(dt);return(-1);}/**數(shù)據(jù)范圍檢查...*/if(dt->month<1||dt->month>12||dt->day<1||dt->day>31||dt->hour<0||dt->hour>23||dt->minute<0||dt->minute>59||dt->second<0||dt->second>59){/**如果日期信息超出范圍...*/free(dt);return(-1);}/**轉(zhuǎn)換ISO時間到以秒為單位的UNIX時間...*/tmdata.tm_year=dt->year-1900;tmdata.tm_mon=dt->month-1;tmdata.tm_day=dt->day;tmdata.tm_hour=dt->hour;tmdata.tm_min=dt->minute;tmdata.tm_sec=dt->second;dt->unix=gmtime(&tmdata);/**設(shè)置自定義節(jié)點數(shù)據(jù)指針和銷毀函數(shù)指針...*/node->value.custom.data=dt;node->value.custom.destroy=free;/**返回沒有錯誤...*/return(0);}這個函數(shù)成功時返回0,當(dāng)不能正確解碼自定義數(shù)據(jù)或者數(shù)據(jù)內(nèi)容錯誤時返回-1。自定義數(shù)據(jù)節(jié)點包含一個void指針用來保存這個節(jié)點已經(jīng)分配的自定義數(shù)據(jù),還有一個指向銷毀函數(shù)的指針用于當(dāng)節(jié)點被刪除時釋放自定義數(shù)據(jù)。保存回調(diào)接收一個節(jié)點指針并且返回一個包含自定義數(shù)據(jù)值的已經(jīng)分配的字符串。下面的保存回調(diào)函數(shù)可以被用來保存我們的ISO日期/時間類型:char*save_custom(mxml_node_t*node){chardata[255];iso_date_time_t*dt;dt=(iso_date_time_t*)node->custom.data;snprintf(data,sizeof(data),"%04u-%02u-%02uT%02u:%02u:%02uZ",dt->year,dt->month,dt->day,dt->hour,dt->minute,dt->second);return(strdup(data));}你可以注冊這些回調(diào)函數(shù)使用mxmlSetCustomHandlers()函數(shù):mxmlSetCustomHandlers(load_custom,save_custom);改變節(jié)點的值到現(xiàn)在為止所有的例子集中描述了如何創(chuàng)建和加載新的XML數(shù)據(jù)節(jié)點。然而,許多的應(yīng)用程序在它們的工作中需要操縱或者改變節(jié)點,所以Mini-XML提供了一些函數(shù)來安全的改變節(jié)點的值并且不會發(fā)生內(nèi)存泄漏。已有的節(jié)點可以被改變通過使用函數(shù)mxmlSetElement(),mxmlSetInteger(),mxmlSetOpaque(),mxmlSetReal(),mxmlSetText(),和mxmlSetTextf()。例如:使用下面的函數(shù)調(diào)用可以改變一個文本節(jié)點到包含字符串"new"并且具有前導(dǎo)的空白字符:mxml_node_t*node;mxmlSetText(node,1,"new");格式化的文本mxmlNewTextf()和mxmlSetTextf()函數(shù)分別是創(chuàng)建和改變文本節(jié)點,使用printf-風(fēng)格的格式字符串和參數(shù)。例如:使用下面的函數(shù)調(diào)用來創(chuàng)建一個新的文本節(jié)點包含一個構(gòu)造的文件名:mxml_node_t*node;node=mxmlNewTextf(node,1,"%s/%s",path,filename);索引Mini-XML提供了一些函數(shù)來管理節(jié)點的索引。當(dāng)前的實現(xiàn)提供了同樣的功能就像mxmlFindElement()一樣。使用索引優(yōu)勢是可以使搜索和枚舉XML元素顯著加快。唯一不利的是每個索引都是一個關(guān)于這個XML文檔的靜態(tài)快照,所以索引不適合當(dāng)相對于它的搜索操作,XML數(shù)據(jù)更加頻繁更新時的情況。上面的創(chuàng)建一個索引近似相當(dāng)于遍歷這個XML文檔樹。在索引中的節(jié)點被按照XML元素名和它的參數(shù)值進(jìn)行排序。這些索引被保存在mxml_index_t結(jié)構(gòu)中。用mxmlIndexNew()函數(shù)可以創(chuàng)建一個新的索引:mxml_node_t*tree;mxml_index_t*ind;ind=mxmlIndexNew(tree,"element","attribute");第一個參數(shù)是需要進(jìn)行索引的XML節(jié)點樹。通常是一個指向?xml元素的節(jié)點。第二個參數(shù)包含了需要進(jìn)行索引的XML元素;使用NULL值將按照字母順序索引所有的XML元素節(jié)點。第三個參數(shù)包含了需要進(jìn)行索引的屬性;使用NULL將使只有XML元素名字被索引。當(dāng)索引被建立后,函數(shù)mxmlIndexEnum(),mxmlIndexFind(),andmxmlIndexReset()可以被用來訪問索引中的節(jié)點。函數(shù)mxmlIndexReset()被用來重置在索引中的"當(dāng)前"節(jié)點指針,允許你在同一個索引中進(jìn)行新的搜索和枚舉遍歷。典型應(yīng)用是你將在你調(diào)用函數(shù)mxmlIndexEnum()和mxmlIndexFind()之前調(diào)用這個函數(shù)。函數(shù)mxmlIndexEnum()用來枚舉在索引中的每一個節(jié)點,可以在一個循環(huán)中使用,如下所示:mxml_node_t*node;mxmlIndexReset(ind);while((node=mxmlIndexEnum(ind))!=NULL){//dosomethingwithnode}函數(shù)mxmlIndexFind()定位下一次在索引中出現(xiàn)的XML元素名和屬性值。它可以被用于發(fā)現(xiàn)在索引中的所有匹配的XML元素,如下所示:mxml_node_t*node;mxmlIndexReset(ind);while((node=mxmlIndexFind(ind,"element","attr-value"))!=NULL){//dosomethingwithnode}第二和第三個參數(shù)分別表示XML元素名和屬性值。使用NULL指針用來返回索引中所有的XML元素或者屬性。如果XML元素名和屬性值同時為NULL則相當(dāng)于調(diào)用函數(shù)mxmlIndexEnum。當(dāng)我們使用完這個索引后,使用函數(shù)mxmlIndexDelete()來刪除它:mxmlIndexDelete(ind);SAX(流方式解析)加載文檔Mini-XML支持一個關(guān)于簡單XMLAPI(SAX)的實現(xiàn),以允許你通過節(jié)點流的方式加載和處理XML文檔。另外允許你處理任何大小的XML文件,Mini-XML的實現(xiàn)也允許你為下一步的處理而只在內(nèi)存中保留XML文檔的一部分。ThemxmlSAXLoadFd,mxmlSAXLoadFile,和mxmlSAXLoadString函數(shù)提供了SAX加載的API。每個函數(shù)工作起來就象mxmlLoad函數(shù)一樣,但是使用一個回調(diào)函數(shù)來處理它讀到的每一個節(jié)點?;卣{(diào)函數(shù)接收到一個節(jié)點,一個事件代碼和一個你提供的用戶數(shù)據(jù)指針:voidsax_cb(mxml_node_t*node,mxml_sax_event_tevent,void*data){...dosomething...}事件(event)將是下面的其中一個:MXML_SAX_CDATA-CDATA正在被讀取MXML_SAX_COMMENT-一個注釋正在被讀取MXML_SAX_DATA-數(shù)據(jù)(custom,integer,opaque,real,ortext)正在被讀取MXML_SAX_DIRECTIVE-一個處理指令正在被讀取MXML_SAX_ELEMENT_OPEN-一個"打開"元素節(jié)點正在被讀取,如(<element>)MXML_SAX_ELEMENT_CLOSE-一個"關(guān)閉"元素節(jié)點正在被讀取,如(</element>)XML元素將被釋放在一個"關(guān)閉"元素被處理后。所有其他的節(jié)點在他們被處理后都被釋放。SAX回調(diào)函數(shù)可以保留這個節(jié)點,通過調(diào)用函數(shù)mxmlRetain。例如:下面的SAX回調(diào)函數(shù)將保留所有的節(jié)點,就像一個普通的內(nèi)存加載一樣:voidsax_cb(mxml_node_t*node,mxml_sax_event_tevent,void*data){if(event!=MXML_SAX_ELEMENT_CLOSE)mxmlRetain(node);}更多的典型SAX回調(diào)函數(shù)將只保留后面需要處理的這個XML文檔的一小部分。例如,下面的SAX回調(diào)函數(shù)將保留一個XHTML文件的標(biāo)題和頭部信息。它總是保留一個XML元素(父節(jié)點)就像<html>,<head>,和<body>,并處理指令節(jié)點就像<?xml...?>和<!DOCTYPE...>:voidsax_cb(mxml_node_t*node,mxml_sax_event_tevent,void*data){if(event==MXML_SAX_ELEMENT_OPEN){/**保留標(biāo)題和頭部*/char*name=node->;if(!strcmp(name,"html")||!strcmp(name,"head")||!strcmp(name,"title")||!strcmp(name,"body")||!strcmp(name,"h1")||!strcmp(name,"h2")||!strcmp(name,"h3")||!strcmp(name,"h4")||!strcmp(name,"h5")||!strcmp(name,"h6"))mxmlRetain(node);}elseif(event==MXML_SAX_DIRECTIVE)mxmlRetain(node);elseif(event==MXML_SAX_DATA&&node->parent->ref_count>1){/**如果父節(jié)點被保留,那么這個數(shù)據(jù)節(jié)點最好是也被保留。*/mxmlRetain(node);}}這個結(jié)果框架文檔樹可以被搜素就像一個使用函數(shù)mxmlLoad加載的一樣。例如,一個過濾器程序用來從標(biāo)準(zhǔn)輸入(stdin)中讀取一個XHTML文檔,并顯示在文檔中的標(biāo)題和標(biāo)頭,如下所示:mxml_node_t*doc,*title,*body,*heading;doc=mxmlSAXLoadFd(NULL,0,MXML_TEXT_CALLBACK,sax_cb,NULL);title=mxmlFindElement(doc,doc,"title",NULL,NULL,MXML_DESCEND);if(title)print_children(title);body=mxmlFindElement(doc,doc,"body",NULL,NULL,MXML_DESCEND);if(body){for(heading=body->child;heading;heading=heading->next)print_children(heading);}使用mxmldoc工具這一章描述了如何使用mxmldoc(1)程序自動從c和c++源文件中生成文檔?;A(chǔ)知識最初開發(fā)是用來生成Mini-XML和CUPSAPI的文檔,現(xiàn)在mxmldoc是一個通用工具實現(xiàn)了掃描C和C++源文件以生成HTML和man手冊頁文檔與一個描述這些源文件中的函數(shù)、類型和宏的定義的XML文件。不像一些流行的文檔生成工具如Doxygen或Javadoc,mxmldoc使用"在線"注釋并不是注釋頭文件,允許更加自然的代碼文檔。缺省情況下,mxmldoc生成HTML文檔個,例如:下面的命令將掃描所有的在當(dāng)前目錄下的C源代碼和頭文件并生成一個HTML文檔文件叫filename.html:mxmldoc*.h*.c>filename.htmlENTER你也可以指定創(chuàng)建一個包含所有源文件信息的XML文件。例如,下面的命令創(chuàng)建一個XML文件filename.xml并添加到這個HTML文件中:mxmldocfilename.xml*.h*.c>filename.htmlENTER--no-output選項關(guān)閉標(biāo)準(zhǔn)的HTML輸出:mxmldoc--no-outputfilename.xml*.h*.cENTER你可以再次運行mxmldoc通過這個XML文件來生成HTML文檔:mxmldocfilename.xml>filename.htmlENTER--manfilename選項來告訴mxmldoc創(chuàng)建一個手冊頁(manpage)代替HTML文檔,例如:mxmldoc--manfilenamefilename.xml\>filename.manENTERmxmldoc--manfilename*.h*.c\>filename.manENTERmxmldoc--manfilenamefilename.xml*.h*.c\>filename.manENTER注釋你的代碼在上面已經(jīng)提到,mxmldoc查看在線注釋來描述你源文件中的函數(shù)、類型以及常量。Mxmldoc將為你源文件中"所有"公開的命名生成文檔,所有以下劃線開始的名稱和被使用@private@指令注解的名稱被認(rèn)為是“私有”的而不生成文檔。出現(xiàn)在函數(shù)或者類型定義前面的注釋被用來生出這個函數(shù)或者類型的文檔。出現(xiàn)在參數(shù)、定義、返回類型或者變量定義被用來生成它們的注釋。例如:下列代碼片斷定義一個包含key/vaue的結(jié)構(gòu)以及一個創(chuàng)建這個結(jié)構(gòu)的新實例的函數(shù):/*Akey/valuepair.Thisisusedwiththedictionarystructure.*/structkeyval{char*key;/*Keystring*/char*val;/*Valuestring*/};/*Createanewkey/valuepair.*/structkeyval*/*Newkey/valuepair*/new_keyval(constchar*key,/*Keystring*/constchar*val)/*Valuestring*/{...}Mxmldoc總是知道并從注釋字符串中移除多余的(*)號,所以下面的這個注釋字符串:/**ComputethevalueofPI.**ThefunctionconnectstoanInternetserver*thatstreamsaudioofmathematicalmonks*chantingthefirst100digitsofPI.*/將被顯示為:ComputethevalueofPI.ThefunctionconnectstoanInternetserverthatstreamsaudioofmathematicalmonkschantingthefirst100digitsofPI.注釋中也可以包含@name...@這樣的特殊指令字符串:@deprecated@-標(biāo)識一個條目為不支持并阻止它的使用@private@-標(biāo)識一個條目為為私有的所以它將不被包含在文檔中。@since...@-標(biāo)識一個條目為為從一個特別重要的發(fā)布更新。從@since到@間的文本在文檔中將被高亮顯示,如:@sinceCUPS1.3@。標(biāo)題、分段名和簡介Mxmldoc也提供了一些選項來設(shè)置生成的文檔中的標(biāo)題、分段名和簡介。The--titletext選項指定了文檔的標(biāo)題。標(biāo)題字符串通常放在引號內(nèi):mxmldocfilename.xml\--title"MyFamousDocumentation"\>filename.htmlENTER--sectionname選項指定了文檔的分段名。對于HTML文檔,這個名字放在一個HTML注釋塊中,如下所示:<!--SECTION:name-->對于手冊頁(manpages),分段名通常是一個數(shù)字("3"),或者是一個數(shù)字后面跟著廠商名如("3acme")。這個分段名被使用在手冊頁(manpages)中的.TH指令里:.THmylibrary3acme"MyTitle"...缺省手冊頁(manpages)的分段名輸出是"3"。對于HTML輸出沒有缺省的分段名。最后,--introfilename選項指定了一個文件來嵌入到在標(biāo)題和分段名之后和生成文檔的前面。對于HTML文檔,這個文件必須兼容HTML并且不能使用DOCTYPE,html,andbody元素。.對于手冊頁文檔,這個文件必須兼容有效的nroff(1)文本.庫參考手冊內(nèi)容函數(shù)mxmlAddmxmlDeletemxmlElementDeleteAttrmxmlElementGetAttrmxmlElementSetAttrmxmlElementSetAttrfmxmlEntityAddCallbackmxmlEntityGetNamemxmlEntityGetValuemxmlEntityRemoveCallbackmxmlFindElementmxmlIndexDeletemxmlIndexEnummxmlIndexFindmxmlIndexNewmxmlIndexResetmxmlLoadFdmxmlLoadFilemxmlLoadStringmxmlNewCDATAmxmlNewCustommxmlNewElementmxmlNewIntegermxmlNewOpaquemxmlNewRealmxmlNewTextmxmlNewTextfmxmlNewXMLmxmlReleasemxmlRemovemxmlRetainmxmlSAXLoadFdmxmlSAXLoadFilemxmlSAXLoadStringmxmlSaveAllocStringmxmlSave

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論