之前處理XML文件時,就是用這套工具橫行江湖,Expat提供細緻的函式讀寫xml文件,SCEW則是把Expat函式包裝成亮麗的界面供使用者更方便的存取xml,個人覺的,這兩套函式庫實在不輸給.net System.xml下的API

首先下載expat libraryscew library,這兩套軟體的使用方式很簡單,執行configure,make,make install後,就可以使用它們的library,而我這邊的範例編譯時用static link,所以我都直接連接它們的.a函式庫檔

Makefile的範例如下

ALL : example 
 
example : example.c 
$(CC) -I./scew-0.4.0/scew/ -o example example.c libscew.a libexpat.a 
clean :
rm example

SCEW write xml的方法大概就五組API如下
(1)創造xml tree: tree = scew_tree_create();
(2)加入root element: scew_tree_add_root(scew_tree*, char*);
(3)加入root element的子element: scew_element_add(scew_element*,char*);
(4)加入element attribute: scew_element_add_attr_pair(scew_element*, char*, char*);;
(5)加入element content: scew_element_set_contents(scew_element*, char *);

寫入xml文件的範例如下

int CreateXML() 
{ 
scew_tree* tree = NULL;
scew_element* root = NULL;
scew_element* element = NULL;
scew_element* sub_element = NULL;
scew_element* sub_sub_element = NULL;
scew_attribute* attribute = NULL;
 
tree = scew_tree_create();
root = scew_tree_add_root(tree, "scew_test");
 
/* Add an element and set element contents. */ 
element = scew_element_add(root, "element1");
scew_element_set_contents(element, "element contents.");
 
/* Add an element with an attribute pair (name, value). */ 
element = scew_element_add(root, "element2");
scew_element_add_attr_pair(element, "attribute", "value");
 
element = scew_element_add(root, "element3");
scew_element_add_attr_pair(element, "attribute1", "value1");
/**
* Another way to add an attribute. You loose attribute ownership,
* so there is no need to free it.
*/ 
attribute = scew_attribute_create("attribute2", "value2");
scew_element_add_attr(element, attribute);
 
element = scew_element_add(root, "element4");
sub_element = scew_element_add(element, "sub_element1");
scew_element_add_attr_pair(sub_element, "attribute", "value");
 
sub_element = scew_element_add(element, "sub_element2");
scew_element_add_attr_pair(sub_element, "attribute1", "value1");
scew_element_add_attr_pair(sub_element, "attribute2", "value2");
 
sub_sub_element = scew_element_add(sub_element, "sub_sub_element1");
scew_element_add_attr_pair(sub_sub_element, "attribute1", "value1");
scew_element_add_attr_pair(sub_sub_element, "attribute2", "value2");
scew_element_add_attr_pair(sub_sub_element, "attribute3", "value3");
/* Check attribute2 replacement. */ 
scew_element_add_attr_pair(sub_sub_element, "attribute2", "new_value2");
scew_element_set_contents(sub_sub_element, "element contents.");
 
scew_writer_tree_file(tree, "example.xml");
scew_tree_free(tree);
 
return 0;
}

執行範例會製造出如下內容的xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 
<scew_test>
<element1>element contents.</element1>
<element2 attribute="value"/>
<element3 attribute1="value1" attribute2="value2"/>
<element4>
<sub_element1 attribute="value"/>
<sub_element2 attribute1="value1" attribute2="value2">
<sub_sub_element1 attribute1="value1" attribute2="new_value2" attribute3="value3">element contents.</sub_sub_element1>
</sub_element2>
</element4>
</scew_test>

而SCEW讀取xml的方法大約有6組API
(1)創造xml parser: parser = scew_parser_create;
(2)讀入xml檔案: scew_parser_load_file(scew_parser*,char*)
(3)讀出element name: scew_element_name(scew_element*)
(4)讀出element attribute: scew_attribute_next(scew_element*, scew_attribute*)
(5)讀出element content: scew_element_contents(scew_element*)
(6)尋找子element: scew_element_next(scew_element*, scew_element*)

讀取xml文件的範例如下

void print_attributes(scew_element* element) 
{ 
scew_attribute* attribute = NULL;
 
if (element != NULL) 
{ 
/**
* Iterates through the element's attribute list, printing the
* pair name-value.
*/ 
attribute = NULL;
while ((attribute = scew_attribute_next(element, attribute)) != NULL) 
printf(" %s=\"%s\"", scew_attribute_name(attribute),scew_attribute_value(attribute));
} 
} 
 
 
 
int PrintElement(scew_element* element) 
{ 
scew_element* child = NULL;
XML_Char const* contents = NULL;
 
printf("element name: %s ", scew_element_name(element));
print_attributes(element);
contents = scew_element_contents(element);
if (contents == NULL) 
printf("\n\n");
else printf("\n%s content:%s\n\n",scew_element_name(element),contents);
 
/**
* Call print_element function again for each child of the
* current element.
*/ 
while ((child = scew_element_next(element, child)) != NULL) 
PrintElement(child);
 
return 0;
 
} 
int ReadXML() 
{ 
scew_tree* tree = NULL;
scew_parser* parser = NULL;
scew_element* element=NULL,*parent=NULL;
/**
* Creates an SCEW parser. This is the first function to call.
*/ 
parser = scew_parser_create();
scew_parser_ignore_whitespaces(parser, 1);
if (!scew_parser_load_file(parser,"example.xml")) return 0;
tree = scew_parser_tree(parser);
PrintElement(scew_tree_root(tree));//traverse all child and siblings of tree
/* Remember to free tree (scew_parser_free does not free it) */ 
scew_tree_free(tree);
 
/* Frees the SCEW parser */ 
scew_parser_free(parser);
return 0;

完整的範例程式請點此下載

最後修改日期: 3 6 月, 2022

作者

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。