mini-XML 中文文檔

Mini-XML 程序員開發手冊, Version 2.5

目錄



序言

構建,安裝,以及打包Mini-XML

Mini-XML 入門

更多的 Mini-XML 編程技術

使用 mxmldoc 工具

Mini-XML 許可信息

發行說明 庫參考手冊

XML方案 (用於自動化文檔生成工具 mxmldoc)


0 序言

這份程序員參考手冊描述了 Mini-XML 2.5版本, 一個小型的 XML 解析庫,使用它可以使你的C或者C++應用程序方便的進行XML數據文件的讀寫

Mini-XML 最初是爲了 Gutenprint 項目而開發,目的是爲了替換既大又笨重的 libxml2 庫, 想要實現一個小型且易於使用的一些東西. 它開始於2003年6月的一個早晨,當時羅伯特發表了下面幾句話到開發者列表:

"這真是糟糕,我們需要libxml2,但反覆看來,我們的XML解析器僅需要我們可以操作的一小部分。"

我做了以下回復:

"考慮到你使用XML僅在一個有限的範圍中,那麼只使用幾百行代碼來編寫一個微型XML (mini-XML) API,應該是很簡單的。"

我接受了這個挑戰,用了兩天的時間進行瘋狂的編碼,並且公開發布了第一個mini-XML版本,總共是696行代碼。然後,羅伯特迅速把mini-XML整合到 Gutenprint 中,並且移除了libxml2庫

感謝很多不同的開發者給我的回饋和支持, 從那以後,Mini-XML逐漸發展爲一個提供更多完整的XML實現,當前已經高達3441行代碼,但已經可以和103893行代碼的libxml2 2.6.9版本相比較了。

譯者:僅用了兩天時間,作者真是大牛啊!我較喜歡Mini-XML,我也用過 TinyXML,libexpat,libxml2等解析器,相比之下Mini-XML實現了一個非常簡潔且功能適用的解析器,很適合我的需求:DOM型 解析器、解析小型的XML文件,不進行錯誤恢復及校驗,簡單易用,且使用純ANSI-C實現,方便移植到嵌入系統中。評價:很好很強大,而且很簡單。 Z.F

除了Gutenprint ,mini-XML當前已經應用於以下的項目/應用軟件:

如果您希望將您的項目添加到此列表或者從此列表中刪除,或者如果您有任何意見和想法,或者想要發佈關於使用mini-XML的經驗,請給我發電子郵件( [email protected]

本文檔組織結構

本手冊由以下章節和附錄組成:

詞法約定

在這篇手冊中使用了一些字體和風格的約定.下面是一些例子含義和使用說明:

lpstat
lpstat(1)
命令名稱;如果在一章中第一次提及這個系統命令或者函數,則後面跟隨手冊頁編號。
譯者:上面指Linux 的manpages 手冊,使用man命令查看。Z.F


/var
/usr/share/cups/data/testprint.ps
文件或者目錄.

Request ID is Printer-123
屏幕輸出.

lp -d printer filename ENTER
用戶輸入的文字,特殊鍵如ENTER 總是使用大寫.

12.3
文本中的數字,使用(.)來表示小數點.

縮略詞

下面是在本手冊中使用的縮略詞:

Gb
GB, 即 1073741824 字節,1*1024*1024*1024 字節

kb
即 1024 字節,1*1024 字節

Mb
兆, or 1048576 bytes,1*1024*1024 字節

UTF-8, UTF-16
統一的字符編碼標準, 8-位 或 16-位

W3C
萬維網聯盟

XML
可擴展標記語言

其他參考

The Unicode Standard, Version 4.0, Addison-Wesley, ISBN 0-321-18578-1
定義了用於XML的Unicode字符集.

Extensible Markup Language (XML) 1.0 (Third Edition)
W3C制定的XML標準.

法律資料

The Mini-XML library is copyright 2003-2008 by Michael Sweet.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.


1 構建,安裝,以及打包Mini-XML

這一章描述瞭如何在你的系統上使用源碼包構建,安裝以及打包Mini-XML,你將需要一個ANSI/ISO-C兼容的C編譯器來構建Mini- XML,GCC可以工作,這也是大多數廠家的C編譯器。如果你需要在Windows平臺上構建, 我們建議使用Virtual C++環境和解決方案文件.對於其他的操作系統,你在C編譯器之外需要一個POSIX兼容的shell和make 程序. .

編譯 Mini-XML

Mini-XML 同時具備基於 autoconf的配置腳本和Virtual C++的解決方案,可以用來編譯庫和關聯的其他工具.

使用 Visual C++ 編譯

打開在目錄 vcnet 下的 mxml.sln 解決方案. 選擇需要構建的配置,"Debug" (缺省選項) 或者 "Release", 並且 從 Build 菜單中選擇 Build Solution 項.

使用命令行工具編譯

在你的系統上鍵入下面的命令來配置Mini-XML源代碼:

    ./configure ENTER

缺省的安裝前綴是 /usr/local , 這可以被覆蓋使用 --prefix 選項:

    ./configure --prefix=/foo ENTER

其他配置選項可以使用命令--help 選項進行查看:

    ./configure --help ENTER

當你配置完畢,使用make(1) 程序來構建並且運行測試程序來校驗是否工作正常,如下:

    make ENTER

安裝 Mini-XML

如果你使用 Visual C++, 分別拷貝 mxml.lib mxml.h 文件到 Visual C++ lib include 目錄.

否則,使用make 命令和install 參數來安裝Mini-XML到配置的目錄中:

    make install ENTER

創建 Mini-XML 包

Mini-XML 包含兩個文件可以被用來創建二進制發行包.第一個文件是 mxml.spec 可以被使用通過 rpmbuild(8) 軟件來創建Red Hat 包管理器("RPM")的發行包,通常用於Linux平臺. rpmbuild 可以自己進行軟件編譯, 你可以爲它提供一個Mini-XML 的tar文件來編譯整個包,使用以下命令:

    rpmbuild -ta mxml-version
.tar.gz ENTER

第二個文件是 mxml.list 被用於 epm(1) 程序創建不同格式的軟件包. epm 程序可以從以下網址獲得:

    http://www.easysw.com/epm/

使用make 命令通過 epm 目標 來構建一個針對你的系統的便攜的本地包:

    make epm ENTER

爲了你方便,這些包保存在子目錄 dist 中.便攜包利用腳本和tar文件安裝軟件到目標系統中.在展開包文件後,使用 mxml.install 腳本來安裝這個軟件.

這些本地包可以是本地操作系統的原生格式:紅帽Linux 的RPM , Debian Linux的DPKG, Solaris的PKG, 等等.使用相應的命令來安裝這些原生包.


2 Mini-XML 入門

這一章描述瞭如何寫一個程序使用Mini-XML來訪問XML文件中的數據.Mini-XML提供了以下功能:

  • 在內存中創建和管理XML文檔的函數.
  • 讀UTF-8和UTF-16 編碼的XML文件和字符串.
  • 寫UTF-8 編碼的XML文件和字符串.
  • 支持任意的元素名稱,屬性以及屬性值,沒有任何其他限制,僅受限於有效內存.
  • 支持整形、浮點、自定義("CDATA")和文本數據類型在"葉"節點.
  • 提供"查找"、"索引"、以及"步進"函數可以很簡單的訪問XML文檔中的數據.

Mini-XML 不進行基於"XML方案(SCHEMA)"文件或者其他內容源定義信息的校驗和其他類型的處理 ,也不支持其他組織所要求的XML規範.

基礎知識

Mini-XML 提供的一個你需要包含的頭文件:

    #include <mxml.h>

把Mini-XML庫連接到你的應用程序使用 -lmxml 選項:

    gcc -o myprogram myprogram.c -lmxml ENTER

如果你已經安裝pkg-config(1) 軟件, 你可以使用它來爲你的安裝確定適當的編譯和連接選項:

    pkg-config --cflags mxml ENTER

pkg-config --libs mxml ENTER

節點

每一塊XML文件中的信息片斷(元素、文本、數字)是一個存儲在內存中的"節點(nodes)" .節點使用 mxml_node_t 結構進行定義. 它的type 成員變量定義了節點類型(element, integer, opaque, real, or text) 決定了需要從聯合(union)類型的成員變量 value 中獲取的值.

表 2-1: Mini-XML 節點值的成員變量
類型 節點成員
用戶定義 void * node->value.custom.data
XML元素 char * node->value.element.name
整數 int node->value.integer
不透明字符串 char * node->value.opaque
浮點數 double node->value.real
文本 char * node->value.text.string
譯者:節點類型定義枚舉參見:mxml_type_e 。 Mini-XML中的節點類型定義和其他有些解析器有些不同,其中整數、浮點、和文本節點是指在一個XML元素中一系列的使用空格作爲分割的值,每個元素 可以擁有多個以上節點,並可以選擇使用空格分開,如:<abc>aa bb cc</abc>,Mini-MXML在使用參數:MXML_TEXT_CALLBACK進行載入時,將在abc元素下面生成3個text類 型的子節點。在創建時也可以使用同樣的方式創建節點。整數和浮點也是同樣方式,但如果轉換失敗則MiniXML報錯。而不透明字符串類型(OPAQUE) 則不進行字符串分割,在載入時需要使用MXML_OPAQUE_CALLBACK參數,將所有字符串形成一個子節點。詳情見:使用加載回調函數 。 Z.F

每一個節點總是有一個成員變量:user_data 可以允許你爲每一個節點關聯你需要的應用數據.

新的節點可以使用以下函數進行創建 mxmlNewElement , mxmlNewInteger , mxmlNewOpaque , mxmlNewReal , mxmlNewText mxmlNewTextf mxmlNewXML . 只有 elements 可以擁有子節點,頂級節點必須是一個 element , 通常是<?xml version="1.0"?> 使用mxmlNewXML() 函數創建的節點.

每個節點都有一些關聯節點的指針,上(parent ), 下( child ), 左(prev ), and 右(next ) 相對應於當前節點. 如果你有一個XML文件如下所示:

    <?xml version="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>

那麼在內存中的文件節點樹看上去如下所示:

    ?xml
|
data
|
node - node - node - group - node - node
| | | | | |
val1 val2 val3 | val7 val8
|
node - node - node
| | |
val4 val5 val6

這裏"-"指向下一個節點,"|"指向第一個子節點。

當你使用完畢這些XML數據後,使用函數 mxmlDelete 來釋放指定節點或者整個XML樹節點和它下面所有子節點的內存:

    mxmlDelete(tree);

創建 XML 文檔

你可以在內存中創建和更新XML文檔,使用 mxmlNew 一系列函數. 下面的代碼將創建上一章描述的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 函數來創建所有XML文件都需要的標頭 <?xml version="1.0"?> :

    xml = mxmlNewXML("1.0");

然後我們使用mxmlNewElement 函數來創建本文件使用的<data> 節點.第一個參數指定了父節點(xml ) ,第二個參數是元素名 (data ):

    data = mxmlNewElement(xml, "data");

每個在本文件中<node>...</node> 之間的部分使用函數 mxmlNewElement mxmlNewText 來創建. mxmlNewText 的第一個參數指定了父節點 (node ).第二個參數指定了是否在文本之前添加空白字符,在本例中使用0或者false.最後一個參數指定了需要添加的實際文本:

    node = mxmlNewElement(data, "node");
mxmlNewText(node, 0, "val1");

在內存中的XML結果可以被保存或者進行其他處理,就像一個從磁盤或者字符串中讀取的文檔一樣.

加載XML

你可以加載一個XML文件使用函數 mxmlLoadFile :

    FILE *fp;
mxml_node_t *tree;

fp = fopen("filename.xml", "r");
tree = mxmlLoadFile(NULL, fp,
MXML_TEXT_CALLBACK);
fclose(fp);

第一個參數如果有的話則指定了一個存在的XML父節點.一般你將這個參數等於NULL ,除非你想要連接多個XML源. 如果此參數等於NULL ,那麼指定的XML文件必須是一個完整的XML文檔,文檔頭部要包含?xml 元素.

第二個參數指定了一個標準的文件流,使用 fopen() 或者 popen() 進行打開. 你也可以使用stdin ,如果你想要實現一個XML過濾器程序.

第三個參數指定了一個回調函數用於一個新的XML元素節點直接返回的子節點的值類型: MXML_CUSTOM , MXML_IGNORE , MXML_INTEGER , MXML_OPAQUE , MXML_REAL , or MXML_TEXT . 加載回調函數的細節在第三章 做了詳細描述. 示例代碼使用 MXML_TEXT_CALLBACK 常量指定文檔中所有的數據節點都包含使用以空格字符分割的文本的值. 其他標準的回調還有 MXML_IGNORE_CALLBACK , MXML_INTEGER_CALLBACK , MXML_OPAQUE_CALLBACK , 和MXML_REAL_CALLBACK .

函數mxmlLoadString 可以從一個字符串中載入XML節點樹:

    char buffer[8192];
mxml_node_t *tree;

...
tree = mxmlLoadString(NULL, buffer,
MXML_TEXT_CALLBACK);

第一個和第三個參數和 mxmlLoadFile() 用法一樣. 第二個參數指定了指定了字符串或者字符緩衝區用於加載XML,當父節點參數爲NULL 時內容必須爲完整的XML文檔,包括XML頭?xml 元素.

保存 XML

你可以保存XML文件使用 mxmlSaveFile 函數:

    FILE *fp;
mxml_node_t *tree;

fp = fopen("filename.xml", "w");
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
fclose(fp);

第一個參數爲想要保存的XML節點樹,一般應該是一個指向你的XML文檔頂級節點?xml 的節點指針.

第二個單數是一個標準文件流,使用 fopen() 或者 popen() 來打開. 你也可以使用stdout 如果你想要實現一個XML過濾器程序.

第三個參數是一個空白回調函數用來控制保存文件時插入的"空白"字符."空白回調"的詳細信息參見 第三章 . 以上的示例代碼使用了MXML_NO_CALLBACK 常量來指定不需要特別的空白處理.

函數mxmlSaveAllocString , 和mxmlSaveString 保存XML節點樹到一個字符串中:

    char buffer[8192];
char *ptr;
mxml_node_t *tree;

...
mxmlSaveString(tree, buffer, sizeof(buffer),
MXML_NO_CALLBACK);

...
ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);

第一個和最後一個參數的用法和函數 mxmlSaveFile() 一樣. 函數mxmlSaveString 給出了一個指針和長度的參數來保存XML文檔到一個固定大小的緩衝區中。, mxmlSaveAllocString() 返回了使用malloc分配的一個字符串緩衝區malloc() .

自動折行控制

當我們保存XML文檔時, Mini-XML一般在第75列進行折行,因爲這樣在終端下最易讀. 函數 mxmlSetWrapMargin 可以覆蓋缺省的折行界限:

    /* 設置自動折行到 132 列*/
mxmlSetWrapMargin(132);

/* 取消自動折行*/
mxmlSetWrapMargin(0);

搜索和遍歷節點

函數mxmlWalkPrev and mxmlWalkNext 可以被用來遍歷XML節點樹:

    mxml_node_t *node;

node = mxmlWalkPrev(current, tree,
MXML_DESCEND);

node = mxmlWalkNext(current, tree,
MXML_DESCEND);

另外,你可以搜索一個命名的XML元素/節點,使用函數 mxmlFindElement :

    mxml_node_t *node;

node = mxmlFindElement(tree, tree, "name",
"attr", "value",
MXML_DESCEND);

參數name , attr , 和value 可以被設置爲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",
"http://www.easysw.com/",
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);

你也可以使用同樣的功能進行遍歷:

    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))
{
... do something ...
}

參數MXML_DESCEND 可以是下面三個常量之一:

  • MXML_NO_DESCEND 含義是不查看任何的子節點在XML元素層次中,僅查看同級的夥伴節點或者父節點直到到達頂級節點或者給出的樹的頂級節點.

    "group"節點的上一個節點時它左面的"node"子節點,下一個節點是"group"右面的"node"子節點..

  • MXML_DESCEND_FIRST 含義是向下搜索到一個節點的第一個匹配子節點,但不再繼續向下搜索。你一般使用於遍歷一個父節點的直接的子節點。 ,如:在上面的例子中的所有在"?xml"父節點下的所有的"node"和"group"子節點。.

    這個模式僅適用於搜索(search)功能,遍歷功能(walk)對待它和 MXML_DESCEND 一樣,因爲每次調用都是首次調用。

  • MXML_DESCEND 含義是一直向下直到樹的根部. "group"節點的上一個節點將是"val3"節點,下一個節點將是"group"的下面的第一個子節點。

    如果你要使用函數mxmlWalkNext() 從根結點"?xml" 遍歷到整個樹的結束, 那麼這個順序將如下所示:

    ?xml data node val1 node val2 node val3 group node val4 node val5 node val6 node val7 node val8

    如果你從"val8"開始並使用函數mxmlWalkPrev() 進行遍歷, 這個順序將是反的,結束於"?xml"節點.


3 更多的 Mini-XML 編程技術

這一章顯示了更多的在你的應用程序中使用Mini-XML的方法。

Load Callbacks

第二章 介紹了函數 mxmlLoadFile() mxmlLoadString() . 這些函數的最後一個參數是一個回調函數,決定了在一個XML文檔中每個數據節點的值的類型。

Mini-XML 爲簡單XML數據文件定義了幾個標準的回調函數:

  • MXML_INTEGER_CALLBACK - 所有的數據節點包含以空格分割的整數。
  • MXML_OPAQUE_CALLBACK - 所有的數據節點包含"不透明"字符串(CDATA)。
  • MXML_REAL_CALLBACK - 所有的數據節點包含以空格分割的浮點數。
  • MXML_TEXT_CALLBACK - 所有的數據節點包含以空格分割的文本字符串。

你可以爲更復雜的XML文檔提供你自己的回調函數。你的回調函數將接收到一個到當前XML元素節點的指針並且必須爲這個XML元素節點返回一個直接子節點的值類型: MXML_INTEGER , MXML_OPAQUE , MXML_REAL , 或MXML_TEXT .這個函數在這個XML元素和它的全部屬性被讀取以後 被調用,所以你可以查看這個XML元素的名稱、屬性以及屬性的值來決定適當的返回值類型。

下面的回調函數查看一個名稱爲"type"的屬性或者XML元素的名字來決定它的子節點的值類型:

    mxml_type_t
type_cb(mxml_node_t *node)
{
const char *type;

/*
* 你可以查看屬性和/或使用XML元素名,所在層次,等等
*/

type = mxmlElementGetAttr(node, "type");
if (type == NULL)
type = node->value.element.name;

if (!strcmp(type, "integer"))
return (MXML_INTEGER);
else if (!strcmp(type, "opaque"))
return (MXML_OPAQUE);
else if (!strcmp(type, "real"))
return (MXML_REAL);
else
return (MXML_TEXT);
}

要使用這個回調函數,只需要在你調用任何加載函數時簡單的使用它的名字:

    FILE *fp;
mxml_node_t *tree;

fp = fopen("filename.xml", "r");
tree = mxmlLoadFile(NULL, fp, type_cb );
fclose(fp);

保存回調

第二章 也介紹了 mxmlSaveFile() , mxmlSaveString() , 和 mxmlSaveAllocString() 函數。這些函數的最後一個參數是一個回調函數被用來自動在一個XML文檔中添加空白字符。

你的回調函數將在每個XML元素被調用四次,傳入參數爲一個到這個節點的指針和一個"where"的值: MXML_WS_BEFORE_OPEN , MXML_WS_AFTER_OPEN , MXML_WS_BEFORE_CLOSE , 或者MXML_WS_AFTER_CLOSE 。如果不需要插入空白字符這個回調函數將返回 NULL ,否則返回字符串(空白、跳格、回車和換行)將被插入。

下面的空白回調可以被用來爲XHTML輸出添加空白字符,來使它在一般的文本編輯器中更加易讀:

    const char *
whitespace_cb(mxml_node_t *node,
int where)
{
const char *name;

/*
* 我們可以在任何XML元素之前或之後有條件的添加換行。這些是一些常見的HTML元素。
*/

name = node->value.element.name;

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"))
{
/*
* 在打開之前和關閉之後時換行。
*/

if (where == MXML_WS_BEFORE_OPEN ||
where == MXML_WS_AFTER_CLOSE)
return ("/n");
}
else if (!strcmp(name, "dl") ||
!strcmp(name, "ol") ||
!strcmp(name, "ul"))
{
/*
* 在列表元素前後都添加換行。
*/

return ("/n");
}
else if (!strcmp(name, "dd") ||
!strcmp(name, "dt") ||
!strcmp(name, "li"))
{
/*
* 添加一個"跳格"在<li>, * <dd>,
* 和 <dt>之前, 以及一個換行在他們後面...
*/

if (where == MXML_WS_BEFORE_OPEN)
return ("/t");
else if (where == MXML_WS_AFTER_CLOSE)
return ("/n");
}

/*
* 如果不需要添加空白字符則返回NULL。
*/

return (NULL);
}

要使用這些回調函數,只需要在你調用任何保存函數時簡單使用它的名字:

    FILE *fp;
mxml_node_t *tree;

fp = fopen("filename.xml", "w");
mxmlSaveFile(tree, fp, whitespace_cb );
fclose(fp);

用戶定義數據類型

Mini-XML 支持通過全局的載入和保存回調函數使用自定義數據類型。 每次只能有一組回調函數被同時激活,然而你的回調函數可以爲支持多種所需要的自定義數據類型來保存更多的信息。 節點類型 MXML_CUSTOM 表示一個自定義數據內容的節點。

加載回調接收一個到當前數據節點的指針和一個不透明字符串數據從XML源中並且將字符集轉換爲UTF-8編碼。例如:如果我們想要支持定製的日期/時間類型並且編碼爲"yyyy-mm-ddThh:mm:ssZ" (ISO 格式), 那麼加載回調函數如下所示:

    typedef struct
{
unsigned year, /* Year */
month, /* Month */
day, /* Day */
hour, /* Hour */
minute, /* Minute */
second; /* Second */
time_t unix; /* UNIX time */
} iso_date_time_t;

int
load_custom(mxml_node_t *node,
const char *data)
{
iso_date_time_t *dt;
struct tm tmdata;

/*
* 分配數據結構...
*/

dt = calloc(1, sizeof(iso_date_time_t));

/*
* 嘗試從數據字符串中讀取6個無符號整數..
*/

if (sscanf(data, "%u-%u-%uT%u:%u:%uZ",
&(dt->year), &(dt->month),
&(dt->day), &(dt->hour),
&(dt->minute),
&(dt->second)) != 6)
{
/*
* 如果不能讀取到數字,釋放分配的結構並返回一個錯誤...
*/

free(dt);

return (-1);
}

/*
* 數據範圍檢查...
*/

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

/*
* 轉換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);

/*
* 設置自定義節點數據指針和銷燬函數指針...
*/

node->value.custom.data = dt;
node->value.custom.destroy = free;

/*
* 返回沒有錯誤...
*/

return (0);
}

這個函數成功時返回0,當不能正確解碼自定義數據或者數據內容錯誤時返回-1。自定義數據節點包含一個void 指針用來保存這個節點已經分配的自定義數據,還有一個指向銷燬函數的指針用於當節點被刪除時釋放自定義數據。

保存回調接收一個節點指針並且返回一個包含自定義數據值的已經分配的字符串。下面的保存回調函數可以被用來保存我們的ISO日期/時間類型:

    char *
save_custom(mxml_node_t *node)
{
char data[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));
}

你可以註冊這些回調函數使用 mxmlSetCustomHandlers() 函數:

    mxmlSetCustomHandlers(load_custom
,save_custom
);

改變節點的值

到現在爲止所有的例子集中描述瞭如何創建和加載新的XML數據節點。然而,許多的應用程序在它們的工作中需要操縱或者改變節點,所以Mini-XML提供了一些函數來安全的改變節點的值並且不會發生內存泄漏。

已有的節點可以被改變通過使用函數 mxmlSetElement() , mxmlSetInteger() , mxmlSetOpaque() , mxmlSetReal() , mxmlSetText() , 和 mxmlSetTextf() 。例如:使用下面的函數調用可以改變一個文本節點到包含字符串"new"並且具有前導的空白字符:

    mxml_node_t *node;

mxmlSetText(node, 1, "new");

格式化的文本

mxmlNewTextf() mxmlSetTextf() 函數分別是創建和改變文本節點,使用printf -風格的格式字符串和參數。例如:使用下面的函數調用來創建一個新的文本節點包含一個構造的文件名:

    mxml_node_t *node;


node = mxmlNewTextf(node, 1, "%s/%s",
path, filename);

索引

Mini-XML 提供了一些函數來管理節點的索引。當前的實現提供了同樣的功能就像 mxmlFindElement() 一樣。使用索引優勢是可以使搜索和枚舉XML元素顯著加快。唯一不利的是每個索引都是一個 關於這個XML文檔的靜態快照,所以索引不適合當相對於它的搜索操作,XML數據更加頻繁更新時的情況。上面的創建一個索引近似相當於遍歷這個XML文檔 樹。在索引中的節點被按照XML元素名和它的參數值進行排序。

這些索引被保存在mxml_index_t 結構中。用mxmlIndexNew() 函數可以創建一個新的索引:

    mxml_node_t *tree;
mxml_index_t *ind;

ind = mxmlIndexNew(tree, "element",
"attribute");

第一個參數是需要進行索引的XML節點樹。通常是一個指向?xml 元素的節點。

第二個參數包含了需要進行索引的XML元素;使用NULL 值將按照字母順序索引所有的XML元素節點。

第三個參數包含了需要進行索引的屬性;使用NULL 將使只有XML元素名字被索引。

當索引被建立後,函數 mxmlIndexEnum() , mxmlIndexFind() , and mxmlIndexReset() 可以被用來訪問索引中的節點。 函數 mxmlIndexReset() 被用來重置在索引中的"當前"節點指針,允許你在同一個索引中進行新的搜索和枚舉遍歷。典型應用是你將在你調用函數mxmlIndexEnum() mxmlIndexFind() 之前調用這個函數。

函數mxmlIndexEnum() 用來枚舉在索引中的每一個節點,可以在一個循環中使用,如下所示:

    mxml_node_t *node;

mxmlIndexReset(ind);

while ((node = mxmlIndexEnum(ind)) != NULL)
{
// do something with node
}

函數mxmlIndexFind() 定位下一次在索引中出現的XML元素名和屬性值。它可以被用於發現在索引中的所有匹配的XML元素,如下所示:

    mxml_node_t *node;

mxmlIndexReset(ind);

while ((node = mxmlIndexFind(ind, "element",
"attr-value"))
!= NULL)
{
// do something with node
}

第二和第三個參數分別表示XML元素名和屬性值。使用 NULL 指針用來返回索引中所有的XML元素或者屬性。如果XML元素名和屬性值同時爲NULL 則相當於調用函數 mxmlIndexEnum

當我們使用完這個索引後,使用函數 mxmlIndexDelete() 來刪除它:

    mxmlIndexDelete(ind);

SAX (流方式解析) 加載文檔

Mini-XML支持一個關於簡單XML API (SAX)的實現,以允許你通過節點流的方式加載和處理XML文檔。另外允許你處理任何大小的XML文件,Mini-XML的實現也允許你爲下一步的處理而只在內存中保留XML文檔的一部分。

The mxmlSAXLoadFd , mxmlSAXLoadFile , 和 mxmlSAXLoadString 函數提供了SAX加載的API。每個函數工作起來就象 mxmlLoad 函數一樣,但是使用一個回調函數來處理它讀到的每一個節點。

回調函數接收到一個節點,一個事件代碼和一個你提供的用戶數據指針:

    void
sax_cb(mxml_node_t *node,
mxml_sax_event_t event,
void *data)
{
... do something ...
}

事件(event)將是下面的其中一個:

  • MXML_SAX_CDATA - CDATA 正在被讀取
  • MXML_SAX_COMMENT - 一個註釋正在被讀取
  • MXML_SAX_DATA - 數據(custom, integer, opaque, real, or text) 正在被讀取
  • MXML_SAX_DIRECTIVE - 一個處理指令正在被讀取
  • MXML_SAX_ELEMENT_OPEN - 一個"打開"元素節點正在被讀取,如( <element> )
  • MXML_SAX_ELEMENT_CLOSE - 一個"關閉"元素節點正在被讀取,如( </element> )

XML元素將被 釋放 在一個"關閉"元素被處理後。所有其他的節點在他們被處理後都被釋放。SAX回調函數可以 保留 這個節點,通過調用函數 mxmlRetain 。例如:下面的SAX回調函數將保留所有的節點,就像一個普通的內存加載一樣:

    void
sax_cb(mxml_node_t *node,
mxml_sax_event_t event,
void *data)
{
if (event != MXML_SAX_ELEMENT_CLOSE)
mxmlRetain(node);
}

更多的典型SAX回調函數將只保留後面需要處理的這個XML文檔的一小部分。例如,下面的SAX回調函數將保留一個XHTML文件的標題和頭部信息。它總是保留一個XML元素(父節點)就像<html> , <head> , 和 <body> ,並處理指令節點就像 <?xml ... ?><!DOCTYPE ... >

    void
sax_cb(mxml_node_t *node,
mxml_sax_event_t event,
void *data)
{
if (event == MXML_SAX_ELEMENT_OPEN)
{
/*
* 保留標題和頭部
*/

char *name = node->value.element.name;

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);
}
else if (event == MXML_SAX_DIRECTIVE)
mxmlRetain(node);
else if (event == MXML_SAX_DATA &&
node->parent->ref_count > 1)
{
/*
* 如果父節點被保留,那麼這個數據節點最好是也被保留。
*/

mxmlRetain(node);
}
}

這個結果框架文檔樹可以被搜素就像一個使用函數mxmlLoad 加載的一樣。例如,一個過濾器程序用來從標準輸入(stdin)中讀取一個XHTML文檔,並顯示在文檔中的標題和標頭,如下所示:

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

4 使用mxmldoc 工具

這一章描述瞭如何使用mxmldoc(1) 程序自動從c和c++源文件中生成文檔。

基礎知識

最初開發是用來生成Mini-XML 和CUPS API的文檔,現在mxmldoc 是一個通用工具實現了掃描C和C++源文件以生成HTML和man手冊頁文檔與一個描述這些源文件中的函數、類型和宏的定義的XML文件。不像一些流行的文檔生成工具如Doxygen 或 Javadoc, mxmldoc 使用"在線"註釋並不是註釋頭文件,允許更加自然的代碼文檔。

缺省情況下,mxmldoc 生成HTML文檔個,例如:下面的命令將掃描所有的在當前目錄下的C源代碼和頭文件並生成一個HTML文檔文件叫 filename.html :

    mxmldoc *.h *.c >filename.html ENTER

你也可以指定創建一個包含所有源文件信息的XML文件。例如,下面的命令創建一個XML文件 filename.xml 並添加到這個HTML文件中:

    mxmldoc filename.xml *.h *.c >filename.html ENTER

--no-output 選項關閉標準的HTML輸出:

    mxmldoc --no-output filename.xml *.h *.c ENTER

你可以再次運行mxmldoc 通過這個XML文件來生成HTML文檔:

    mxmldoc filename.xml >filename.html ENTER

--man filename 選項來告訴mxmldoc 創建一個手冊頁(man page)代替HTML文檔,例如:

    mxmldoc --man filename filename.xml /
>filename.man ENTER


mxmldoc --man filename *.h *.c /
>filename.man ENTER


mxmldoc --man filename filename.xml *.h *.c /
>filename.man ENTER

註釋你的代碼

在上面已經提到,mxmldoc 查看在線註釋來描述你源文件中的函數、類型以及常量。Mxmldoc 將爲你源文件中"所有"公開的命名生成文檔,所有以下劃線開始的名稱和被使用@private@ 指令註解的名稱被認爲是“私有”的而不生成文檔。

出現在函數或者類型定義前面的註釋被用來生出這個函數或者類型的文檔。出現在參數、定義、返回類型或者變量定義被用來生成它們的註釋。例如:下列代碼片斷定義一個包含key/vaue的結構以及一個創建這個結構的新實例的函數:

    /* A key/value pair. This is used with the
dictionary structure. */

struct keyval
{
char *key; /* Key string */
char *val; /* Value string */
};

/* Create a new key/value pair. */

struct keyval * /* New key/value pair */
new_keyval(
const char *key, /* Key string */
const char *val) /* Value string */
{
...
}

Mxmldoc 總是知道並從註釋字符串中移除多餘的(*)號,所以下面的這個註釋字符串:

    /*
* Compute the value of PI.
*
* The function connects to an Internet server
* that streams audio of mathematical monks
* chanting the first 100 digits of PI.
*/

將被顯示爲:

    Compute the value of PI.

The function connects to an Internet server
that streams audio of mathematical monks
chanting the first 100 digits of PI.

註釋 中也可以包含@name ...@ 這樣的特殊指令字符串:

  • @deprecated@ - 標識一個條目爲不支持並阻止它的使用
  • @private@ - 標識一個條目爲爲私有的所以它將不被包含在文檔中。
  • @since ...@ - 標識一個條目爲爲從一個特別重要的發佈更新。從@since@ 間的文本在文檔中將被高亮顯示,如: @since CUPS 1.3@

標題、分段名和簡介

Mxmldoc 也提供了一些選項來設置生成的文檔中的標題、分段名和簡介。The --title text 選項指定了文檔的標題。標題字符串通常放在引號內:

    mxmldoc filename.xml /
--title "My Famous Documentation" /
>filename.html ENTER

--section name 選項指定了文檔的分段名。對於HTML文檔,這個名字放在一個HTML註釋塊中,如下所示:

    <!-- SECTION: name -->

對於手冊頁(man pages), 分段名通常是一個數字("3"),或者是一個數字後面跟着廠商名如("3acme")。這個分段名被使用在手冊頁(man pages)中的.TH 指令裏:

    .TH mylibrary 3acme "My Title" ...

缺省手冊頁(man pages)的分段名輸出是"3"。對於HTML輸出沒有缺省的分段名。

最後,--intro filename 選項指定了一個文件來嵌入到在標題和分段名之後和生成文檔的前面。對於HTML文檔,這個文件必須兼容HTML並且不能使用DOCTYPE , html , and body 元素。 .對於手冊頁文檔,這個文件必須兼容有效的nroff(1) 文本.


A Mini-XML 許可信息

The Mini-XML library and included programs are provided under the terms of the GNU Library General Public License (LGPL) with the following exceptions:

LGPL 許可協議中文版本參見:GNU通用公共許可證 Z.F
  1. Static linking of applications to the Mini-XML library does not constitute a derivative work and does not require the author to provide source code for the application, use the shared Mini-XML libraries, or link their applications against a user-supplied version of Mini-XML.

    If you link the application to a modified version of Mini-XML, then the changes to Mini-XML must be provided under the terms of the LGPL in sections 1, 2, and 4.

  2. You do not have to provide a copy of the Mini-XML license with programs that are linked to the Mini-XML library, nor do you have to identify the Mini-XML license in your program or documentation as required by section 6 of the LGPL.

GNU LIBRARY GENERAL PUBLIC LICENSE

Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.]

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.

This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it.

For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights.

Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library.

Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license.

The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such.

Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better.

However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries.

The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the libary" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library.

Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you".

A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.

The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.

1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.

    (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.

In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.

Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.

This option is useful when you wish to copy part of the code of the Library into a program that is not a library.

4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.

If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.

5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.

However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.

When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.

If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)

Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.

You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:

    a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)

    b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.

    c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.

    d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.

For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.

7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.

    b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.

8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.

10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.

11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Libraries

If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).

To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

    one line to give the library's name and an idea of what it does.
    Copyright (C) year name of author

    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:

    Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker.

    signature of Ty Coon , 1 April 1990 Ty Coon, President of Vice

That's all there is to it!


B 發行說明

Changes in Mini-XML 2.5

  • The mxmldoc program now makes greater use of CSS and supports a --css option to embed an alternate stylesheet.
  • The mxmldoc program now supports --header and --footer options to insert documentation content before and after the generated content.
  • The mxmldoc program now supports a --framed option to generate framed HTML output.
  • The mxmldoc program now creates a table of contents including any headings in the --intro file when generating HTML output.
  • The man pages and man page output from mxmldoc did not use "/-" for dashes (STR #68)
  • The debug version of the Mini-XML DLL could not be built (STR #65)
  • Processing instructions and directives did not work when not at the top level of a document (STR #67)
  • Spaces around the "=" in attributes were not supported (STR #67)

Changes in Mini-XML 2.4

  • Fixed shared library build problems on HP-UX and Mac OS X.
  • The mxmldoc program did not output argument descriptions for functions properly.
  • All global settings (custom, error, and entity callbacks and the wrap margin) are now managed separately for each thread.
  • Added mxmlElementDeleteAttr() function (STR #59)
  • mxmlElementSetAttrf() did not work (STR #57)
  • mxmlLoad*() incorrectly treated declarations as parent elements (STR #56)
  • mxmlLoad*() incorrectly allowed attributes without values (STR #47)
  • Fixed Visual C++ build problems (STR #49)
  • mxmlLoad*() did not return NULL when an element contained an error (STR #46)
  • Added support for the apos character entity (STR #54)
  • Fixed whitespace detection with Unicode characters (STR #48)
  • mxmlWalkNext() and mxmlWalkPrev() did not work correctly when called with a node with no children as the top node (STR #53)

Changes in Mini-XML 2.3

  • Added two exceptions to the LGPL to support static linking of applications against Mini-XML
  • The mxmldoc utility can now generate man pages, too.
  • Added a mxmlNewXML() function
  • Added a mxmlElementSetAttrf() function (STR #43)
  • Added a snprintf() emulation function for the test program (STR #32)
  • Added the _CRT_SECURE_NO_DEPRECATE definition when building on VC++ 2005 (STR #36)
  • mxmlLoad*() did not detect missing > characters in elements (STR #41)
  • mxmlLoad*() did not detect missing close tags at the end of an XML document (STR #45)
  • Added user_data and ref_count members to mxml_node_t structure
  • Added mxmlReleaseNode() and mxmlRetainNode() APIs for reference-counted nodes
  • Added mxmlSetWrapMargin() to control the wrapping of XML output
  • Added conditional check for EINTR error code for certain Windows compilers that do not define it (STR #33)
  • The mxmldoc program now generates correct HTML 4.0 output - previously it generated invalid XHTML
  • The mxmldoc program now supports "@deprecated@, "@private@", and "@since version@" comments
  • Fixed function and enumeration type bugs in mxmldoc
  • Fixed the XML schema for mxmldoc
  • The mxmldoc program now supports --intro, --section, and --title options
  • The mxmlLoad*() functions could leak a node on an error (STR #27)
  • The mxml_vsnprintf() function could get in an infinite loop on a buffer overflow (STR #25)
  • Added new mxmlNewCDATA() and mxmlSetCDATA() functions to create and set CDATA nodes, which are really just special element nodes
  • Added new MXML_IGNORE type and MXML_IGNORE_CB callback to ignore non-element nodes, e.g. whitespace
  • mxmlLoad*() did not treat custom data as opaque, so whitespace characters would be lost

Changes in Mini-XML 2.2.2

  • mxmlLoad*() did not treat custom data as opaque, so whitespace characters would be lost.

Changes in Mini-XML 2.2.1

  • mxmlLoadFd(), mxmlLoadFile(), and mxmlLoadString() now correctly return NULL on error (STR #21)
  • mxmlNewInteger(), mxmlNewOpaque(), mxmlNewReal(), mxmlNewText(), and mxmlNewTextf() incorrectly required a parent node (STR #22)
  • Fixed an XML output bug in mxmldoc.
  • The "make install" target now uses the install command to set the proper permissions on UNIX/Linux/OSX.
  • Fixed a MingW/Cygwin compilation problem (STR #18)

Changes in Mini-XML 2.2

  • Added shared library support (STR #17)
  • mxmlLoad*() now returns an error when an XML stream contains illegal control characters (STR #10)
  • mxmlLoad*() now returns an error when an element contains two attributes with the same name in conformance with the XML spec (STR #16)
  • Added support for CDATA (STR #14, STR #15)
  • Updated comment and processing instruction handling - no entity support per XML specification.
  • Added checking for invalid comment termination ("--->" is not allowed)

Changes in Mini-XML 2.1

  • Added support for custom data nodes (STR #6)
  • Now treat UTF-8 sequences which are longer than necessary as an error (STR #4)
  • Fixed entity number support (STR #8)
  • Fixed mxmlLoadString() bug with UTF-8 (STR #7)
  • Fixed entity lookup bug (STR #5)
  • Added mxmlLoadFd() and mxmlSaveFd() functions.
  • Fixed multi-word UTF-16 handling.

Changes in Mini-XML 2.0

  • New programmers manual.
  • Added Visual C++ project files for Microsoft Windows users.
  • Added optimizations to mxmldoc, mxmlSaveFile(), and mxmlIndexNew() (STR #2)
  • mxmlEntityAddCallback() now returns an integer status (STR #2)
  • Added UTF-16 support (input only; all output is UTF-8)
  • Added index functions to build a searchable index of XML nodes.
  • Added character entity callback interface to support additional character entities beyond those defined in the XHTML specification.
  • Added support for XHTML character entities.
  • The mxmldoc utility now produces XML output which conforms to an updated XML schema, described in the file "doc/mxmldoc.xsd".
  • Changed the whitespace callback interface to return strings instead of a single character, allowing for greater control over the formatting of XML files written using Mini-XML. THIS CHANGE WILL REQUIRE CHANGES TO YOUR 1.x CODE IF YOU USE WHITESPACE CALLBACKS.
  • The mxmldoc utility now produces XML output which conforms to an updated XML schema, described in the file "doc/mxmldoc.xsd".
  • Changed the whitespace callback interface to return strings instead of a single character, allowing for greater control over the formatting of XML files written using Mini-XML. THIS CHANGE WILL REQUIRE CHANGES TO YOUR 1.x CODE IF YOU USE WHITESPACE CALLBACKS.
  • The mxmldoc utility is now capable of documenting C++ classes, functions, and structures, and correctly handles C++ comments.
  • Added new modular tests for mxmldoc.
  • Updated the mxmldoc output to be more compatible with embedding in manuals produced with HTMLDOC.
  • The makefile incorrectly included a "/" separator between the destination path and install path. This caused problems when building and installing with MingW.

Changes in Mini-XML 1.3

  • Fixes for mxmldoc.
  • Added support for reading standard HTML entity names.
  • mxmlLoadString/File() did not decode character entities in element names, attribute names, or attribute values.
  • mxmlLoadString/File() would crash when loading non- conformant XML data under an existing parent (top) node.
  • Fixed several bugs in the mxmldoc utility.
  • Added new error callback function to catch a variety of errors and log them to someplace other than stderr.
  • The mxmlElementSetAttr() function now allows for NULL attribute values.
  • The load and save functions now properly handle quoted element and attribute name strings properly, e.g. for !DOCTYPE declarations.

Changes in Mini-XML 1.2

  • Added new "set" methods to set the value of a node.
  • Added new formatted text methods mxmlNewTextf() and mxmlSetTextf() to create/set a text node value using printf-style formats.
  • Added new standard callbacks for use with the mxmlLoad functions.
  • Updated the HTML documentation to include examples of the walk and load function output.
  • Added --with/without-ansi configure option to control the strdup() function check.
  • Added --with/without-snprintf configure option to control the snprintf() and vsnprintf() function checks.

Changes in Mini-XML 1.1.2

  • The mxml(3) man page wasn't updated for the string functions.
  • mxmlSaveString() returned the wrong number of characters.
  • mxml_add_char() updated the buffer pointer in the wrong place.

Changes in Mini-XML 1.1.1

  • The private mxml_add_ch() function did not update the start-of-buffer pointer which could cause a crash when using mxmlSaveString().
  • The private mxml_write_ws() function called putc() instead of using the proper callback which could cause a crash when using mxmlSaveString().
  • Added a mxmlSaveAllocString() convenience function for saving an XML node tree to an allocated string.

Changes in Mini-XML 1.1

  • The mxmlLoadFile() function now uses dynamically allocated string buffers for element names, attribute names, and attribute values. Previously they were capped at 16383, 255, and 255 bytes, respectively.
  • Added a new mxmlLoadString() function for loading an XML node tree from a string.
  • Added a new mxmlSaveString() function for saving an XML node tree to a string.
  • Add emulation of strdup() if the local platform does not provide the function.

Changes in Mini-XML 1.0

  • The mxmldoc program now handles function arguments, structures, unions, enumerations, classes, and typedefs properly.
  • Documentation provided via mxmldoc and more in-line comments in the code.
  • Added man pages and packaging files.

Changes in Mini-XML 0.93

  • New mxmldoc example program that is also used to create and update code documentation using XML and produce HTML reference pages.
  • Added mxmlAdd() and mxmlRemove() functions to add and remove nodes from a tree. This provides more flexibility over where the nodes are inserted and allows nodes to be moved within the tree as needed.
  • mxmlLoadFile() now correctly handles comments.
  • mxmlLoadFile() now supports the required "gt", "quot", and "nbsp" character entities.
  • mxmlSaveFile() now uses newlines as whitespace when valid to do so.
  • mxmlFindElement() now also takes attribute name and attribute value string arguments to limit the search to specific elements with attributes and/or values.
  • NULL pointers can be used as "wildcards".
  • Added uninstall target to makefile, and auto-reconfig if Makefile.in or configure.in are changed.
  • mxmlFindElement(), mxmlWalkNext(), and mxmlWalkPrev() now all provide "descend" arguments to control whether they descend into child nodes in the tree.
  • Fixed some whitespace issues in mxmlLoadFile().
  • Fixed Unicode output and whitespace issues in mxmlSaveFile().
  • mxmlSaveFile() now supports a whitespace callback to provide more human-readable XML output under program control.

Changes in Mini-XML 0.92

  • mxmlSaveFile() didn't return a value on success.

Changes in Mini-XML 0.91

  • mxmlWalkNext() would go into an infinite loop.

Changes in Mini-XML 0.9

  • Initial public release.

C 庫參考手冊

內容

函數

mxmlAdd

添加一個節點到樹中

void mxmlAdd (
    mxml_node_t *parent,
    int where,
    mxml_node_t *child,
    mxml_node_t *node
);

參數

parent
父節點
where
添加到哪裏, MXML_ADD_BEFORE or MXML_ADD_AFTER
child
where的子節點或者使用MXML_ADD_TO_PARENT
node
準備添加的節點

說明

添加一個指定的節點到父節點,如果child參數不是NULL,將這個新的節點添加到指定的"child" 的前面或者後面(由where參數決定)。如果child參數是NULL,把新節點添加到子節點列表的最前面(MXML_ADD_BEFORE)或者時子 節點列表的最後面(MXML_ADD_AFTER)。常量MXML_ADD_TO_PARENT 可以被用來指定一個NULL的child指針。

mxmlDelete

刪除一個節點和它的所有的子節點。

void mxmlDelete (
    mxml_node_t *node
);

參數

node
被刪除的節點

說明

如果這個指定的節點有一個父節點,這個函數首先使用mxmlRemove() 函數從它的父節點中移除自己。

 Mini-XML 2.4  mxmlElementDeleteAttr

刪除一個參數

void mxmlElementDeleteAttr (
    mxml_node_t *node,
    const char *name
);

參數

node
XML元素節點
name
屬性名稱

mxmlElementGetAttr

獲取一個參數

const char *mxmlElementGetAttr (
    mxml_node_t *node,
    const char *name
);

參數

node
XML元素節點
name
屬性名稱

返回值

屬性值或者NULL

說明

如果node參數不是一個XML元素或者指定的屬性名不存在則返回NULL。

mxmlElementSetAttr

設置一個屬性。

void mxmlElementSetAttr (
    mxml_node_t *node,
    const char *name,
    const char *value
);

參數

node
XML元素節點
name
屬性名稱
value
屬性值

說明

如果這個屬性名已經存在,這個屬性的值將被替換爲新的字符串值。這個字符串值將被拷貝到這個XML元素節點,如果這個節點不是一個XML元素,則這個函數不做任何事。

 Mini-XML 2.3  mxmlElementSetAttrf

設置一個XML元素屬性使用一個格式化的值。

void mxmlElementSetAttrf (
    mxml_node_t *node,
    const char *name,
    const char *format,
    ...
);

參數

node
XML元素節點
name
屬性名
format
"printf"風格的屬性值
...
需要的附加參數(printf)風格

說明

如果這個屬性名已經存在,這個屬性的值將被替換爲新的格式化字符串值。這個格式化後字符串值將被拷貝到這個XML元素節點,如果這個節點不是一個XML元素,則這個函數不做任何事。

mxmlEntityAddCallback

添加一個回調函數來將XML實體轉換爲Unicode編碼字符。

int mxmlEntityAddCallback (void);

返回值

0 成功, -1 失敗

回調函數用來將類似於"&amp;"之類的XML實體字符串轉化爲用戶設定的Unicode編碼。此函數的原型 應該爲:int mxmlEntityAddCallback(int (*cb)(const char *name)) 參數爲自定義中的回調函數。目前僅支持將實體轉換爲單個字符的轉換,而不支持實體字符串。 Z.F

mxmlEntityGetName

獲取一個字符值對應的XML實體名字。

const char *mxmlEntityGetName (
    int val
);

參數

val
字符值

返回值

XML實體名字或者NULL

說明

如果val不需要被標識爲一個命名的XML實體,返回NULL。

如:val = '&',將返回"&amp;" Z.F

mxmlEntityGetValue

獲取一個代表到一個XML命名實體的字符。

int mxmlEntityGetValue (
    const char *name
);

參數

name
XML實體名字

返回值

字符值或者-1代表錯誤

說明

XML實體名字總是可以被關聯到一個數字常量,如果這個名字未知則返回-1。

mxmlEntityRemoveCallback

刪除一個XML實體回調。

void mxmlEntityRemoveCallback (void);

函數原型應該是:void mxmlEntityRemoveCallback(int (*cb)(const char *name)); Z.F

mxmlFindElement

搜索一個命名的XML元素。

mxml_node_t *mxmlFindElement (
    mxml_node_t *node,
    mxml_node_t *top,
    const char *name,
    const char *attr,
    const char *value,
    int descend
);

參數

node
當前節點
top
頂級節點
name
XML元素名,或者NULL匹配所有元素
attr
屬性名,或者NULL表示不匹配屬性
value
屬性值,或者NULL表示任何值
descend
在XML樹中向下搜索模式: MXML_DESCEND, MXML_NO_DESCEND, 或者 MXML_DESCEND_FIRST

返回值

XMl元素節點或者NULL

說明

搜索可以被XML元素名,屬性名和屬性值所限定;任何名字或者值等於NULL被處理就相當於通配符,所以使 用不同的搜索方法可以被實現用來查看所有的指定名稱的XML元素或者是所有的具有指定屬性的XML元素。參數: descend 確定了是否向下搜索子節點;通常你將使用 MXML_DESCEND_FIRST作爲第一次搜索,然後使用使用 MXML_NO_DESCEND來發現更多的這個節點的直接子節點。 top 節點參數約束了搜索在一個指定節點的子節點中。

mxmlIndexDelete

刪除一個索引。

void mxmlIndexDelete (
    mxml_index_t *ind
);

參數

ind
被刪除的索引

mxmlIndexEnum

返回索引中的下一個節點。

mxml_node_t *mxmlIndexEnum (
    mxml_index_t *ind
);

參數

ind
進行枚舉的索引

返回值

下一個節點或者NULL代表沒有更多的節點

說明

返回節點順序將按照索引的排序被返回。

mxmlIndexFind

搜索下一個匹配的節點。

mxml_node_t *mxmlIndexFind (
    mxml_index_t *ind,
    const char *element,
    const char *value
);

參數

ind
進行搜索的索引
element
如不爲NULL,代表想要搜索的XML元素名。
value
如不爲NULL,代表想要搜索的屬性值。

返回值

節點或者NULL代表沒有發現。

說明

你在第一次使用一個特定的包含"element"和"value"字符串的集合來調用這個函數之前應該首先調用mxmlIndexReset()函數。如果"element"和"value"同時等於NULL則相當於調用了mxmlIndexEnum()函數。

mxmlIndexNew

創建一個新的索引。

mxml_index_t *mxmlIndexNew (
    mxml_node_t *node,
    const char *element,
    const char *attr
);

參數

node
XML 節點樹
element
索引的XML元素名或者NULL代表所有元素
attr
索引的XML屬性名或者NULL代表不使用。

返回值

新的索引

說明

被創建的索引將包含具備指定的元素名和/或屬性所有的節點。如果"element" 和"attr"同時等於NULL,索引將包含一個被排序的完整節點樹的列表。節點被按照XML元素名和選擇的屬性值(如果"attr"參數不等於NULL)進行排序。

mxmlIndexReset

重設索引中的枚舉/搜索指針並且返回索引中的第一個節點。

mxml_node_t *mxmlIndexReset (
    mxml_index_t *ind
);

參數

ind
準備重設的索引

返回值

第一個節點或者NULL代表索引爲空。

說明

這個函數需要被首先調用,在第一次使用函數mxmlIndexEnum() 或 mxmlIndexFind()之前。

mxmlLoadFd

載入一個文件描述符到一個XML節點樹。

mxml_node_t *mxmlLoadFd (
    mxml_node_t *top,
    int fd,
    mxml_load_cb_t cb
);

參數

top
頂部節點
fd
需要進行讀取的文件描述符
cb
回調函數或者 MXML_NO_CALLBACK

返回值

第一個節點或者NULL代表文件不能被讀取。

說明

在指定文件中的所有節點將被添加到所指定的頂部節點。如果沒有"top"頂部節點被提供,這個XML文件必須是規範的並且整個文件只有一個父節點爲<?xml> 。 回調函數返回的值類型將被使用到子節點。如果 MXML_NO_CALLBACK 參數被指定,那麼所有的子節點將都會是MXML_ELEMENT 或者 MXML_TEXT 其中之一的節點。

常量 MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, MXML_REAL_CALLBACK, 和 MXML_TEXT_CALLBACK 定義了將載入指定類型的子節點。

mxmlLoadFile

載入一個文件到一個XML節點樹。

mxml_node_t *mxmlLoadFile (
    mxml_node_t *top,
    FILE *fp,
    mxml_load_cb_t cb
);

參數

top
頂級節點
fp
準備讀取的文件
cb
回調函數或MXML_NO_CALLBACK

返回值

第一個節點或者NULL代表文件不能被讀取。

說明

在指定文件中的所有節點將被添加到所指定的頂部節點。如果沒有"top"頂部節點被提供,這個XML文件必須是規範的並且整個文件只有一個父節點爲<?xml> 。 回調函數返回的值類型將被使用到子節點。如果 MXML_NO_CALLBACK 參數被指定,那麼所有的子節點將都會是MXML_ELEMENT 或者 MXML_TEXT 其中之一的節點.

常量 MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, MXML_REAL_CALLBACK, 和 MXML_TEXT_CALLBACK 定義了將載入指定類型的子節點。

mxmlLoadString

載入一個文件到一個XML節點樹。

mxml_node_t *mxmlLoadString (
    mxml_node_t *top,
    const char *s,
    mxml_load_cb_t cb
);

參數

top
頂級節點
s
準備讀取的字符串
cb
回調函數或MXML_NO_CALLBACK

返回值

第一個節點或者NULL代表字符串中有錯誤。

說明

在指定字符串中的所有節點將被添加到所指定的頂部節點。如果沒有"top"頂部節點被提供,這個XML字符串必須是規範的並且整個文件只有一個父節點爲<?xml> 。 回調函數返回的值類型將被使用到子節點。如果 MXML_NO_CALLBACK 參數被指定,那麼所有的子節點將都會是MXML_ELEMENT 或者 MXML_TEXT 其中之一的節點.

T常量 MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, MXML_REAL_CALLBACK, 和 MXML_TEXT_CALLBACK 定義了將載入指定類型的子節點。

 Mini-XML 2.3  mxmlNewCDATA

創建一個新的CDATA 節點.

mxml_node_t *mxmlNewCDATA (
    mxml_node_t *parent,
    const char *data
);

參數

parent
父節點或者MXML_NO_PARENT
data
數據字符串

返回值

新的節點

說明

新的CDATA節點將被添加到指定父節點的子節點列表的最後,常量 MXML_NO_PARENT 可以被用來指定新的CDATA節點沒有父節點。數據字符串必須是以空字符結尾,並被拷貝到新的CDATA節點。CDATA節點使用 MXML_ELEMENT 節點類型。

 Mini-XML 2.1  mxmlNewCustom

創建一個新的用戶自定義數據節點。

mxml_node_t *mxmlNewCustom (
    mxml_node_t *parent,
    void *data,
    mxml_custom_destroy_cb_t destroy
);

參數

parent
父節點或者 MXML_NO_PARENT
data
指向數據的指針
destroy
銷燬數據使用的函數

返回值

新節點

說明

新的自定義節點將被添加到指定父節點的子節點列表的最後。常量 MXML_NO_PARENT 可以被用來指定新的自定義節點沒有父節點。NULL可以被通過,當數據節點不是動態分配或者是獨立管理時。

最後一句NULL應該是指參數:destroy,表示不使用銷燬函數。 Z.F

mxmlNewElement

創建一個新的XML元素節點。

mxml_node_t *mxmlNewElement (
    mxml_node_t *parent,
    const char *name
);

參數

parent
父節點或MXML_NO_PARENT
name
XML元素名稱

返回值

新節點

說明

新的XML元素節點將被添加到指定父節點的子節點列表的最後。常量 MXML_NO_PARENT 可以被用來指定新的XML元素節點沒有父節點。

mxmlNewInteger

創建一個新的整數節點。

mxml_node_t *mxmlNewInteger (
    mxml_node_t *parent,
    int integer
);

參數

parent
父節點或MXML_NO_PARENT
integer
整形值

返回值

新節點

說明

新的整數節點將被添加到指定父節點的子節點列表的最後。常量 MXML_NO_PARENT 可以被用來指定新的整數節點沒有父節點。

mxmlNewOpaque

創建一個新的不透明字符串節點

mxml_node_t *mxmlNewOpaque (
    mxml_node_t *parent,
    const char *opaque
);

參數

parent
父節點或MXML_NO_PARENT
opaque
不透明字符串

返回值

新節點

說明

新的不透明字符串節點將被添加到指定父節點的子節點列表的最後。常量 MXML_NO_PARENT 可以被用來指定新的不透明字符串節點沒有父節點。這個字符串必須是空字符結尾並被拷貝到新節點。

mxmlNewReal

創建一個新的浮點數節點。

mxml_node_t *mxmlNewReal (
    mxml_node_t *parent,
    double real
);

參數

parent
父節點或MXML_NO_PARENT
real
浮點數值

返回值

新節點

說明

新的浮點數節點將被添加到指定父節點的子節點列表的最後。常量 MXML_NO_PARENT 可以被用來指定新的浮點數節點沒有父節點。

mxmlNewText

創建新的文本分段節點。

mxml_node_t *mxmlNewText (
    mxml_node_t *parent,
    int whitespace,
    const char *string
);

參數

parent
父節點或MXML_NO_PARENT
whitespace
1 = 有前導空格, 0 = 沒有空格
string
字符串

返回值

新節點

說明

新的文本節點將被添加到指定父節點的子節點列表的最後。常量 MXML_NO_PARENT 可以被用來指定新的文本節點沒有父節點。參數:whitespace被用在指定是否在這個節點前面有前導空格。文本字符串必須時以空字符結尾並被拷貝到新的節點。

mxmlNewTextf

創建一個新的格式化的文本分段節點

mxml_node_t *mxmlNewTextf (
    mxml_node_t *parent,
    int whitespace,
    const char *format,
    ...
);

參數

parent
父節點或MXML_NO_PARENT
whitespace
1 = 有前導空格, 0 = 沒有空格
format
"printf"風格的格式化字符串
...
需要的附加參數

返回值

新節點

說明

新的文本節點將被添加到指定父節點的子節點列表的最後。常量 MXML_NO_PARENT 可以被用來指定新的文本節點沒有父節點。參數:whitespace被用在指定是否在這個節點前面有前導空格。格式化字符串必須時以空字符結尾並被格式化到新的節點。

 Mini-XML 2.3  mxmlNewXML

創建一個新的XML文檔樹。

mxml_node_t *mxmlNewXML (
    const char *version
);

參數

version
使用的版本號

返回值

新的 "?xml" 節點

說明

參數 "version" 指定了放在"?xml" 元素節點中的版本號。如果爲NULL則假定爲 "version 1.0"。

 Mini-XML 2.3  mxmlRelease

釋放一個節點。

int mxmlRelease (
    mxml_node_t *node
);

參數

node
節點

返回值

新的引用計數

說明

當引用計數爲0時,這個節點(以及所有子節點)被通過函數 mxmlDelete() 所刪除。

mxmlRemove

移除一個節點從它的父節點中。

void mxmlRemove (
    mxml_node_t *node
);

參數

node
被移除的節點

說明

不釋放節點使用的內存,使用函數 mxmlDelete() 來釋放。如果這個節點沒有父節點則這個函數不做任何事。

 Mini-XML 2.3  mxmlRetain

保留一個節點

int mxmlRetain (
    mxml_node_t *node
);

參數

node
節點

返回值

新的引用計數

 Mini-XML 2.3  mxmlSAXLoadFd

使用SAX回調從一個文件描述符中加載數據到一個XML節點樹。

mxml_node_t *mxmlSAXLoadFd (
    mxml_node_t *top,
    int fd,
    mxml_load_cb_t cb,
    mxml_sax_cb_t sax_cb,
    void *sax_data
);

參數

top
頂級節點
fd
進行讀取的文件描述符
cb
XML節點類型回調函數或者MXML_NO_CALLBACK
sax_cb
SAX 回調函數或者MXML_NO_CALLBACK
sax_data
SAX 用戶數據

返回值

第一個節點或者NULL 代表文件不能被讀取。

說明

在指定文件中的節點將被添加到指定的頂級節點中。如果"top"節點沒有提供,這個XML文件必須是規範的 並且整個文件只有一個父節點爲<?xml> 。回調函數"cb"返回子節點的值類型。如果 MXML_NO_CALLBACK 參數被指定,那麼所有的子節點將都會是MXML_ELEMENT 或者 MXML_TEXT 其中之一的節點。

常量 MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, MXML_REAL_CALLBACK, 和MXML_TEXT_CALLBACK 被定義用於加載指定類型的子節點。

在SAX 回調函數中("sax_cb"),對於所有節點都必須調用mxmlRetain()函數用於保留爲以後使用。否則,節點將在父節點被關閉時或者到達數據、註釋、CDATA和指令節點時被刪除。

 Mini-XML 2.3  mxmlSAXLoadFile

使用SAX回調從一個文件中加載數據到一個XML節點樹。

mxml_node_t *mxmlSAXLoadFile (
    mxml_node_t *top,
    FILE *fp,
    mxml_load_cb_t cb,
    mxml_sax_cb_t sax_cb,
    void *sax_data
);

參數

top
頂級節點
fp
進行讀取的文件
cb
XML節點類型回調函數或者MXML_NO_CALLBACK
sax_cb
SAX 回調函數或者MXML_NO_CALLBACK
sax_data
SAX 用戶數據

返回值

第一個節點或者NULL 代表文件不能被讀取。

說明

在指定文件中的節點將被添加到指定的頂級節點中。如果"top"節點沒有提供,這個XML文件必須是規範的 並且整個文件只有一個父節點爲<?xml> 。回調函數"cb"返回子節點的值類型。如果 MXML_NO_CALLBACK 參數被指定,那麼所有的子節點將都會是MXML_ELEMENT 或者 MXML_TEXT 其中之一的節點。

常量 MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, MXML_REAL_CALLBACK, 和MXML_TEXT_CALLBACK 被定義用於加載指定類型的子節點。

在SAX 回調函數中("sax_cb"),對於所有節點都必須調用mxmlRetain()函數用於保留爲以後使用。否則,節點將在父節點被關閉時或者到達數據、註釋、CDATA和指令節點時被刪除。

 Mini-XML 2.3  mxmlSAXLoadString

使用SAX回調從一個字符串中加載數據到一個XML節點樹。

mxml_node_t *mxmlSAXLoadString (
    mxml_node_t *top,
    const char *s,
    mxml_load_cb_t cb,
    mxml_sax_cb_t sax_cb,
    void *sax_data
);

參數

top
頂級節點
s
準備加載的字符串
cb
XML節點類型回調函數或者MXML_NO_CALLBACK
sax_cb
SAX 回調函數或者MXML_NO_CALLBACK
sax_data
SAX 用戶數據

返回值

第一個節點或者NULL 代表文件不能被讀取。

說明

在指定字符串中的節點將被添加到指定的頂級節點中。如果"top"節點沒有提供,這個XML字符串必須是規 範的並且整個文件只有一個父節點爲<?xml> 。回調函數"cb"返回子節點的值類型。如果 MXML_NO_CALLBACK 參數被指定,那麼所有的子節點將都會是MXML_ELEMENT 或者 MXML_TEXT 其中之一的節點。

常量 MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, MXML_REAL_CALLBACK, 和MXML_TEXT_CALLBACK 被定義用於加載指定類型的子節點。

在SAX 回調函數中("sax_cb"),對於所有節點都必須調用mxmlRetain()函數用於保留爲以後使用。否則,節點將在父節點被關閉時或者到達數據、註釋、CDATA和指令節點時被刪除。

mxmlSaveAllocString

保存一個XML節點樹到一個內部分配的字符串。

char *mxmlSaveAllocString (
    mxml_node_t *node,
    mxml_save_cb_t cb
);

參數

node
準備要寫入的節點
cb
空白回調函數或者MXML_NO_CALLBACK

返回值

分配的字符串或者 NULL

說明

這個函數返回一個指向字符串的指針包含了描述整個XML節點樹的文本。當你使用完這個字符串後需要使用free()函數來釋放。如果這個節點產生了一個空字符或者字符串分配失敗將返回NULL。

回調函數參數指定了一個函數用來在每個XML元素之前或者之後返回一個空白字符串或者NULL。如果指定了MXML_NO_CALLBACK,空格將僅被 添加到具有前導空格的MXML_TEXT節點前面(node->value->text->whitespace = 1)和在一個打開XML元素標籤的屬性名稱前面。

mxmlSaveFd

保存一個XML節點樹到一個文件描述符。

int mxmlSaveFd (
    mxml_node_t *node,
    int fd,
    mxml_save_cb_t cb
);

參數

node
準備要寫入的節點
fd
準備寫入的文件描述符
cb
空白回調函數或者MXML_NO_CALLBACK

返回值

成功返回 0,錯誤返回 -1。

說明

回調函數參數指定了一個函數用來在每個XML元素之前或者之後返回一個空白字符串或者NULL。如果指定了MXML_NO_CALLBACK,空格將僅被 添加到具有前導空格的MXML_TEXT節點前面(node->value->text->whitespace = 1)和在一個打開XML元素標籤的屬性名稱前面。

mxmlSaveFile

保存一個XML節點樹到一個文件。

int mxmlSaveFile (
    mxml_node_t *node,
    FILE *fp,
    mxml_save_cb_t cb
);

參數

node
準備要寫入的節點
fp
準備寫入的文件。
cb
空白回調函數或者MXML_NO_CALLBACK

返回值

成功返回 0,錯誤返回 -1。

說明

回調函數參數指定了一個函數用來在每個XML元素之前或者之後返回一個空白字符串或者NULL。如果指定了MXML_NO_CALLBACK,空格將僅被 添加到具有前導空格的MXML_TEXT節點前面(node->value->text->whitespace = 1)和在一個打開XML元素標籤的屬性名稱前面。

mxmlSaveString

保存一個XML節點樹到一個字符串。

int mxmlSaveString (
    mxml_node_t *node,
    char *buffer,
    int bufsize,
    mxml_save_cb_t cb
);

參數

node
準備要寫入的節點
buffer
字符串緩衝區
bufsize
字符串緩衝區大小
cb
空白回調函數或者MXML_NO_CALLBACK

返回值

字符串大小

說明

這個函數返回字符串需要字節總數,但是最多拷貝(bufsize-1)個字符到指定的buffer中。

如:一個XML樹字符串長度爲200個字節,但緩衝區只有100字節,則返回200,但只拷貝了99個字符,最後一個爲空字符。Z.F

回調函數參數指定了一個函數用來在每個XML元素之前或者之後返回一個空白字符串或者NULL。如果指定了MXML_NO_CALLBACK,空格將僅被 添加到具有前導空格的MXML_TEXT節點前面(node->value->text->whitespace = 1)和在一個打開XML元素標籤的屬性名稱前面。

 Mini-XML 2.3  mxmlSetCDATA

設置一個CDATA元素節點的名稱。

int mxmlSetCDATA (
    mxml_node_t *node,
    const char *data
);

參數

node
準備設置的節點
data
新的數據字符串

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個CDATA節點則節點不發生改變。

 Mini-XML 2.1  mxmlSetCustom

對一個用戶自定義數據節點設置數據和銷燬回調函數。

int mxmlSetCustom (
    mxml_node_t *node,
    void *data,
    mxml_custom_destroy_cb_t destroy
);

參數

node
被設置的節點
data
新的數據指針
destroy
新的銷燬回調函數

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個用戶自定義節點則節點不發生改變。

mxmlSetCustomHandlers

設置對於自定義數據的處理回調函數。

void mxmlSetCustomHandlers (
    mxml_custom_load_cb_t load,
    mxml_custom_save_cb_t save
);

參數

load
加載回調函數
save
保存回調函數

說明

加載回調函數接收一個節點指針和數據字符串,成功時必須返回 0,錯誤時返回一個非0值。

保存回調函數接收一個節點指針,成功時必須返回一個使用malloc分配的字符串,錯誤時返回NULL。

mxmlSetElement

設置XML元素節點的名字。

int mxmlSetElement (
    mxml_node_t *node,
    const char *name
);

參數

node
被設置的節點
name
新的名稱字符串

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個XML元素節點則節點不發生改變。

mxmlSetErrorCallback

設置錯誤信息回調函數。

void mxmlSetErrorCallback (
    mxml_error_cb_t cb
);

參數

cb
錯誤回調函數

mxmlSetInteger

設置一個整數節點的值。

int mxmlSetInteger (
    mxml_node_t *node,
    int integer
);

參數

node
被設置的節點
integer
整數值

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個整數節點則節點不發生改變。

mxmlSetOpaque

設置一個不透明字符串節點的值。

int mxmlSetOpaque (
    mxml_node_t *node,
    const char *opaque
);

參數

node
被設置的節點
opaque
不透明字符串

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個不透明字符串節點則節點不發生改變。

mxmlSetReal

設置一個浮點數節點的值。

int mxmlSetReal (
    mxml_node_t *node,
    double real
);

參數

node
被設置的節點
real
浮點數值

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個浮點數節點則節點不發生改變。

mxmlSetText

設置一個文本節點的值。

int mxmlSetText (
    mxml_node_t *node,
    int whitespace,
    const char *string
);

參數

node
被設置的節點
whitespace
1 = 有前導空格, 0 = 沒有前導空格
string
字符串

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個文本節點則節點不發生改變。

mxmlSetTextf

設置一個文本節點的值爲一個格式化的字符串。

int mxmlSetTextf (
    mxml_node_t *node,
    int whitespace,
    const char *format,
    ...
);

參數

node
被設置的節點
whitespace
1 = 有前導空格, 0 = 沒有前導空格
format
"printf"風格的格式化字符串
...
需要的附加參數

返回值

成功返回 0,失敗返回 -1。

說明

如果這個節點不是一個文本節點則節點不發生改變。

 Mini-XML 2.3  mxmlSetWrapMargin

設置在保存XML數據時的自動折行位置。

void mxmlSetWrapMargin (
    int column
);

參數

column
自動折行的列

說明

當"column" is <= 0時取消自動折行。

mxmlWalkNext

遍歷到XML樹中的下一個邏輯節點。

mxml_node_t *mxmlWalkNext (
    mxml_node_t *node,
    mxml_node_t *top,
    int descend
);

參數

node
當前節點
top
頂級節點
descend
在XML樹中的向下搜索模式 - MXML_DESCEND, MXML_NO_DESCEND, 或者 MXML_DESCEND_FIRST。

返回值

下一個節點或者NULL

說明

"descend"參數控制下一個節點是否考慮第一個子節點。"top"參數約束了遍歷這個節點的所有子節點。

mxmlWalkPrev

遍歷到XML樹中的上一個邏輯節點。

mxml_node_t *mxmlWalkPrev (
    mxml_node_t *node,
    mxml_node_t *top,
    int descend
);

參數

node
當前節點
top
頂級節點
descend
在XML樹中的向下搜索模式 - MXML_DESCEND, MXML_NO_DESCEND, 或者 MXML_DESCEND_FIRST。

返回值

上一個節點或者NULL

說明

"descend"參數控制下一個節點是否考慮第一個子節點。"top"參數約束了遍歷這個節點的所有子節點。

數據類型

mxml_attr_t

XML元素節點的屬性值。

typedef struct mxml_attr_s mxml_attr_t;

mxml_custom_destroy_cb_t

自定義數據銷燬回調函數原型

typedef void (*mxml_custom_destroy_cb_t)(void *);

mxml_custom_load_cb_t

自定義數據加載回調函數原型

typedef int (*mxml_custom_load_cb_t)( mxml_node_t *, const char *);

mxml_custom_save_cb_t

自定義數據保存回調函數原型

typedef char *(*mxml_custom_save_cb_t)( mxml_node_t *);

 Mini-XML 2.1  mxml_custom_t

自定義XML類型值

typedef struct mxml_custom_s mxml_custom_t;

mxml_element_t

XML元素值

typedef struct mxml_element_s mxml_element_t;

mxml_error_cb_t

錯誤回調函數原型

typedef void (*mxml_error_cb_t)(const char *);

mxml_index_t

XML節點索引

typedef struct mxml_index_s mxml_index_t;

mxml_load_cb_t

加載回調函數

typedef mxml_type_t (*mxml_load_cb_t)( mxml_node_t *);

mxml_node_t

XML節點

typedef struct mxml_node_s mxml_node_t;

mxml_save_cb_t

保存回調函數

typedef const char *(*mxml_save_cb_t)( mxml_node_t *, int);

mxml_sax_cb_t

SAX 回調函數

typedef void (*mxml_sax_cb_t)( mxml_node_t *, mxml_sax_event_t, void *);

mxml_sax_event_t

SAX 事件類型.

typedef enum mxml_sax_event_e mxml_sax_event_t;

mxml_text_t

XML文本節點值

typedef struct mxml_text_s mxml_text_t;

mxml_value_t

XML節點值

typedef union mxml_value_u mxml_value_t;

Structures

mxml_attr_s

XML元素的屬性值

struct mxml_attr_s {
    char *name;
    char *value;
};

成員

name
屬性名
value
屬性值

 Mini-XML 2.1  mxml_custom_s

自定義XML節點值

struct mxml_custom_s {
    void *data;
    mxml_custom_destroy_cb_t destroy;
};

成員

data
指向一個自定義數據的指針(已分配的)。
destroy
指向銷燬回調函數的指針

mxml_element_s

XML元素值

struct mxml_element_s {
    mxml_attr_t *attrs;
    char *name;
    int num_attrs;
};

成員

attrs
包含的所有屬性
name
XML元素名稱
num_attrs
包含的屬性數量

mxml_index_s

XML節點索引

struct mxml_index_s {
    int alloc_nodes;
    char *attr;
    int cur_node;
    mxml_node_t **nodes;
    int num_nodes;
};

成員

alloc_nodes
在索引中的已分配的節點數
attr
節點使用的屬性或者NULL
cur_node
當前節點
nodes
包含的節點數組
num_nodes
在索引中的節點總數

mxml_node_s

XML 節點。

struct mxml_node_s {
    struct mxml_node_s *child;
    struct mxml_node_s *last_child;
    struct mxml_node_s *next;
    struct mxml_node_s *parent;
    struct mxml_node_s *prev;
    int ref_count;
    mxml_type_t type;
    void *user_data;
    mxml_value_t value;
};

成員

child
第一個子節點
last_child
最後一個子節點
next
同級的下一個節點(在同一個父節點下)
parent
父節點
prev
同級的上一個節點(在同一個父節點下)
ref_count
使用計數器(引用計數)
type
節點類型
user_data
用戶關聯數據
value
節點值

mxml_text_s

XML文本節點值

struct mxml_text_s {
    char *string;
    int whitespace;
};

成員

string
字符串片斷
whitespace
是否有前導空格?

聯合

mxml_value_u

XML節點值。

union mxml_value_u {
    mxml_custom_t custom;
    mxml_element_t element;
    int integer;
    char *opaque;
    double real;
    mxml_text_t text;
};

成員

custom  Mini-XML 2.1 
自定義數據
element
元素
integer
整數
opaque
不透明字符串
real
浮點數
text
文本片斷

常量

mxml_sax_event_e

SAX 事件類型。

常量

MXML_SAX_CDATA
CDATA 節點
MXML_SAX_COMMENT
註釋節點
MXML_SAX_DATA
數據節點
MXML_SAX_DIRECTIVE
處理指令節點
MXML_SAX_ELEMENT_CLOSE
XML元素關閉節點
MXML_SAX_ELEMENT_OPEN
XML元素開放節點

mxml_type_e

XML 節點類型

常量

MXML_CUSTOM  Mini-XML 2.1 
自定義數據
MXML_ELEMENT
XML 元素幷包含屬性
MXML_IGNORE  Mini-XML 2.3 
忽略/拋棄的節點
MXML_INTEGER
整數值
MXML_OPAQUE
透明字符串值
MXML_REAL
浮點數值
MXML_TEXT
文本片斷

D XML Schema

這個附錄提供了mxmldoc 程序生成XML文件時使用的XML schema。這個schema 的在線版本參見:

    http://www.easysw.com/~mike/mxmldoc.xsd

mxmldoc.xsd


<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Mini-XML 2.3 documentation schema for mxmldoc output.
Copyright 2003-2007 by Michael Sweet.
</xsd:documentation>
</xsd:annotation>

<!-- basic element definitions -->
<xsd:element name="argument" type="argumentType"/>
<xsd:element name="class" type="classType"/>
<xsd:element name="constant" type="constantType"/>
<xsd:element name="description" type="xsd:string"/>
<xsd:element name="enumeration" type="enumerationType"/>
<xsd:element name="function" type="functionType"/>
<xsd:element name="mxmldoc" type="mxmldocType"/>
<xsd:element name="namespace" type="namespaceType"/>
<xsd:element name="returnvalue" type="returnvalueType"/>
<xsd:element name="seealso" type="identifierList"/>
<xsd:element name="struct" type="structType"/>
<xsd:element name="typedef" type="typedefType"/>
<xsd:element name="type" type="xsd:string"/>
<xsd:element name="union" type="unionType"/>
<xsd:element name="variable" type="variableType"/>

<!-- descriptions of complex elements -->
<xsd:complexType name="argumentType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="default" type="xsd:string" use="optional"/>
<xsd:attribute name="name" type="identifier" use="required"/>
<xsd:attribute name="direction" type="direction" use="optional"
default="I"/>
</xsd:complexType>

<xsd:complexType name="classType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="class"/>
<xsd:element ref="enumeration"/>
<xsd:element ref="function"/>
<xsd:element ref="struct"/>
<xsd:element ref="typedef"/>
<xsd:element ref="union"/>
<xsd:element ref="variable"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
<xsd:attribute name="parent" type="xsd:string" use="optional"/>
</xsd:complexType>

<xsd:complexType name="constantType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>

<xsd:complexType name="enumerationType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="constant" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>

<xsd:complexType name="functionType">
<xsd:sequence>
<xsd:element ref="returnvalue" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="argument" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element ref="seealso" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
<xsd:attribute name="scope" type="scope" use="optional"/>
</xsd:complexType>

<xsd:complexType name="mxmldocType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="class"/>
<xsd:element ref="enumeration"/>
<xsd:element ref="function"/>
<xsd:element ref="namespace"/>
<xsd:element ref="struct"/>
<xsd:element ref="typedef"/>
<xsd:element ref="union"/>
<xsd:element ref="variable"/>
</xsd:choice>
</xsd:complexType>

<xsd:complexType name="namespaceType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="class"/>
<xsd:element ref="enumeration"/>
<xsd:element ref="function"/>
<xsd:element ref="struct"/>
<xsd:element ref="typedef"/>
<xsd:element ref="union"/>
<xsd:element ref="variable"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>

<xsd:complexType name="returnvalueType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="structType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="variable"/>
<xsd:element ref="function"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>

<xsd:complexType name="typedefType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>

<xsd:complexType name="unionType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="variable" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>

<xsd:complexType name="variableType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>

<!-- data types -->
<xsd:simpleType name="direction">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="I"/>
<xsd:enumeration value="O"/>
<xsd:enumeration value="IO"/>
</xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="identifier">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[a-zA-Z_(.]([a-zA-Z_(.,)* 0-9])*"/>
</xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="identifierList">
<xsd:list itemType="identifier"/>
</xsd:simpleType>

<xsd:simpleType name="scope">
<xsd:restriction base="xsd:string">
<xsd:enumeration value=""/>
<xsd:enumeration value="private"/>
<xsd:enumeration value="protected"/>
<xsd:enumeration value="public"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章