09
04

Expat+SCEW-操弄XML的瑞士刀

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

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

Makefile的範例如下

  1. ALL : example 
  2.  
  3. example : example.c 
  4. $(CC) -I./scew-0.4.0/scew/ -o example example.c libscew.a libexpat.a 
  5. clean :
  6. 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文件的範例如下

  1. int CreateXML() 
  2. { 
  3. scew_tree* tree = NULL;
  4. scew_element* root = NULL;
  5. scew_element* element = NULL;
  6. scew_element* sub_element = NULL;
  7. scew_element* sub_sub_element = NULL;
  8. scew_attribute* attribute = NULL;
  9.  
  10. tree = scew_tree_create();
  11. root = scew_tree_add_root(tree, "scew_test");
  12.  
  13. /* Add an element and set element contents. */ 
  14. element = scew_element_add(root, "element1");
  15. scew_element_set_contents(element, "element contents.");
  16.  
  17. /* Add an element with an attribute pair (name, value). */ 
  18. element = scew_element_add(root, "element2");
  19. scew_element_add_attr_pair(element, "attribute", "value");
  20.  
  21. element = scew_element_add(root, "element3");
  22. scew_element_add_attr_pair(element, "attribute1", "value1");
  23. /**
  24. * Another way to add an attribute. You loose attribute ownership,
  25. * so there is no need to free it.
  26. */ 
  27. attribute = scew_attribute_create("attribute2", "value2");
  28. scew_element_add_attr(element, attribute);
  29.  
  30. element = scew_element_add(root, "element4");
  31. sub_element = scew_element_add(element, "sub_element1");
  32. scew_element_add_attr_pair(sub_element, "attribute", "value");
  33.  
  34. sub_element = scew_element_add(element, "sub_element2");
  35. scew_element_add_attr_pair(sub_element, "attribute1", "value1");
  36. scew_element_add_attr_pair(sub_element, "attribute2", "value2");
  37.  
  38. sub_sub_element = scew_element_add(sub_element, "sub_sub_element1");
  39. scew_element_add_attr_pair(sub_sub_element, "attribute1", "value1");
  40. scew_element_add_attr_pair(sub_sub_element, "attribute2", "value2");
  41. scew_element_add_attr_pair(sub_sub_element, "attribute3", "value3");
  42. /* Check attribute2 replacement. */ 
  43. scew_element_add_attr_pair(sub_sub_element, "attribute2", "new_value2");
  44. scew_element_set_contents(sub_sub_element, "element contents.");
  45.  
  46. scew_writer_tree_file(tree, "example.xml");
  47. scew_tree_free(tree);
  48.  
  49. return 0;
  50. }

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

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2.  
  3. <scew_test>
  4. <element1>element contents.</element1>
  5. <element2 attribute="value"/>
  6. <element3 attribute1="value1" attribute2="value2"/>
  7. <element4>
  8. <sub_element1 attribute="value"/>
  9. <sub_element2 attribute1="value1" attribute2="value2">
  10. <sub_sub_element1 attribute1="value1" attribute2="new_value2" attribute3="value3">element contents.</sub_sub_element1>
  11. </sub_element2>
  12. </element4>
  13. </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文件的範例如下

  1. void print_attributes(scew_element* element) 
  2. { 
  3. scew_attribute* attribute = NULL;
  4.  
  5. if (element != NULL) 
  6. { 
  7. /**
  8. * Iterates through the element's attribute list, printing the
  9. * pair name-value.
  10. */ 
  11. attribute = NULL;
  12. while ((attribute = scew_attribute_next(element, attribute)) != NULL) 
  13. printf(" %s=\"%s\"", scew_attribute_name(attribute),scew_attribute_value(attribute));
  14. } 
  15. } 
  16.  
  17.  
  18.  
  19. int PrintElement(scew_element* element) 
  20. { 
  21. scew_element* child = NULL;
  22. XML_Char const* contents = NULL;
  23.  
  24. printf("element name: %s ", scew_element_name(element));
  25. print_attributes(element);
  26. contents = scew_element_contents(element);
  27. if (contents == NULL) 
  28. printf("\n\n");
  29. else printf("\n%s content:%s\n\n",scew_element_name(element),contents);
  30.  
  31. /**
  32. * Call print_element function again for each child of the
  33. * current element.
  34. */ 
  35. while ((child = scew_element_next(element, child)) != NULL) 
  36. PrintElement(child);
  37.  
  38. return 0;
  39.  
  40. } 
  41. int ReadXML() 
  42. { 
  43. scew_tree* tree = NULL;
  44. scew_parser* parser = NULL;
  45. scew_element* element=NULL,*parent=NULL;
  46. /**
  47. * Creates an SCEW parser. This is the first function to call.
  48. */ 
  49. parser = scew_parser_create();
  50. scew_parser_ignore_whitespaces(parser, 1);
  51. if (!scew_parser_load_file(parser,"example.xml")) return 0;
  52. tree = scew_parser_tree(parser);
  53. PrintElement(scew_tree_root(tree));//traverse all child and siblings of tree
  54. /* Remember to free tree (scew_parser_free does not free it) */ 
  55. scew_tree_free(tree);
  56.  
  57. /* Frees the SCEW parser */ 
  58. scew_parser_free(parser);
  59. return 0;

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

標籤: linux
評論: 0 | 引用: 0 | 閱讀: 7717
發表評論
暱 稱: 密 碼:
網 址: E - mail:
驗證碼: 驗證碼圖片 選 項:
頭 像:
內 容: