從 PHP 中認識來的 Expat http://download1.csdn.net/down3/20070607/07111232845.gz
- Expat是一個XML的解析器, 透過它可以讓PHP程式解讀XML文件的結構和內容
- 一般XML解析器分為兩種基本類型
- 樹狀解析器(Tree-based parser): XML文件轉換成樹狀結構. 這類解析器 分析整篇文章, 同時提供一個API來訪問所產生樹的每個元素. 其通用 的標準為DOM(文件物件模式)
- 事件解析器(Event-based parser): 將XML文件視為一系列的事件來handler. 當一個特殊事件發生時, 解析器將透過程式所提供的函數來處理.
- 事件解析器 有一個XML文件的資料中心檢視(data-centric view), 也就是說, 它集中在 XML文件的資料部分, 而不是其結構. 這些解析器從頭到尾處理文件, 並將類似於- 元素的開始、元素的結尾、特徵資料的開始等-事件通過回覆(callback)函數報 告給應用程式。
- 而Expat就是屬於 事件解析器 的一種。
- Expat是一個不會去判斷XML文件是否有效的解析器,因此可以忽略任何與文件關 聯的DTD,但是XML文件格式仍然需要完整(表示DTD還是得存在),否則Expat (和其他符合XML標準的解析器一樣)將會隨著出錯資訊而停止。
- 範例如下
藉由 SCEW(scew-0.3.2.tar.gz) 所直接處理的範例- scew_print.c : 用來解讀指定參數的 xml 檔案.
- scew_write.c : 用來寫出指定參數的 xml 檔案.
/** * * @file scew_print.c * @author Aleix Conchillo Flaque <aleix@member.fsf.org> * @date Wed Dec 04, 2002 01:11 * @brief SCEW usage example * * $Id: scew_print.c,v 1.20 2004/01/29 22:38:33 aleix Exp $ * * @if copyright * * Copyright (C) 2002, 2003, 2004 Aleix Conchillo Flaque * * SCEW 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. * * SCEW 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. * * @endif * * This example shows the usage of the API provided by SCEW. It will * print an XML file given as the first program parameter. */ /** * You will probably need to change this include to <scew/scew.h> in you * program. */ #include <scew/scew.h> #include <stdio.h> /* indentation size (in whitespaces) */ int const indent_size = 4; void print_indent(unsigned int indent) { if (indent > 0) { printf("%*s", indent * indent_size, " "); } } 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)); } } } void print_element(scew_element* element, unsigned int indent) { scew_element* child = NULL; XML_Char const* contents = NULL; if (element == NULL) { return; } /** * Prints the starting element tag with its attributes. */ print_indent(indent); printf("<%s", scew_element_name(element)); print_attributes(element); printf(">"); contents = scew_element_contents(element); if (contents == NULL) { printf("/n"); } /** * Call print_element function again for each child of the * current element. */ child = NULL; while ((child = scew_element_next(element, child)) != NULL) { print_element(child, indent + 1); } /* Prints element's content. */ if (contents != NULL) { printf("%s", contents); } else { print_indent(indent); } /** * Prints the closing element tag. */ printf("</%s>/n", scew_element_name(element)); } int main(int argc, char** argv) { scew_tree* tree = NULL; scew_parser* parser = NULL; if (argc < 2) { printf("usage: scew_print file.xml/n"); return EXIT_FAILURE; } /** * Creates an SCEW parser. This is the first function to call. */ parser = scew_parser_create(); scew_parser_ignore_whitespaces(parser, 1); /* Loads an XML file */ if (!scew_parser_load_file(parser, argv[1])) { scew_error code = scew_error_code(); printf("Unable to load file (error #%d: %s)/n", code, scew_error_string(code)); if (code == scew_error_expat) { enum XML_Error expat_code = scew_error_expat_code(parser); printf("Expat error #%d (line %d, column %d): %s/n", expat_code, scew_error_expat_line(parser), scew_error_expat_column(parser), scew_error_expat_string(expat_code)); } return EXIT_FAILURE; } tree = scew_parser_tree(parser); /* Prints full tree */ print_element(scew_tree_root(tree), 0); /* 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; }
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/** * * @file scew_write.c * @author Aleix Conchillo Flaque <aleix@member.fsf.org> * @date Sun Mar 30, 2003 12:21 * @brief SCEW usage example * * $Id: scew_write.c,v 1.5 2004/01/29 22:38:34 aleix Exp $ * * @if copyright * * Copyright (C) 2002, 2003, 2004 Aleix Conchillo Flaque * * SCEW 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. * * SCEW 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. * * @endif * * This example shows the usage of the API provided by SCEW. It will * create a new XML and write it to a file. * * We will create an XML with the follwing structure: * * <scew_test> * <element> * element contents. * </element> * <element attribute="value"/> * <element attribute1="value1" attribute2="value2"/> * <element> * <sub_element attribute="value"/> * <sub_element attribute1="value1" attribute2="value2"> * <sub_sub_element attribute="value"> * element contents. * </sub_sub_element> * </sub_element> * </element> * </scew_test> */ /** * You will probably need to change this include to <scew/scew.h> in you * program. */ #include <scew/scew.h> #include <stdio.h> int main(int argc, char** argv) { 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; if (argc < 2) { printf("usage: scew_write new_file.xml/n"); return EXIT_FAILURE; } /** * Create an empty XML tree in memory, and add a root element * "scew_test". */ tree = scew_tree_create(); root = scew_tree_add_root(tree, "scew_test"); /* Add an element and set element contents. */ element = scew_element_add(root, "element"); scew_element_set_contents(element, "element contents."); /* Add an element with an attribute pair (name, value). */ element = scew_element_add(root, "element"); scew_element_add_attr_pair(element, "attribute", "value"); element = scew_element_add(root, "element"); 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, "element"); sub_element = scew_element_add(element, "sub_element"); scew_element_add_attr_pair(sub_element, "attribute", "value"); sub_element = scew_element_add(element, "sub_element"); 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_element"); scew_element_add_attr_pair(sub_sub_element, "attribute", "value"); scew_element_set_contents(sub_sub_element, "element contents."); /** * Save an XML tree to a file. */ if (!scew_writer_tree_file(tree, argv[1])) { printf("Unable to create %s/n", argv[1]); return EXIT_FAILURE; } /* Frees the SCEW tree */ scew_tree_free(tree); return 0; }