转自: http://blog.csdn.net/axlrosek/article/details/1641950
- Expat是一個XML的解析器, 透過它可以讓PHP程式解讀XML文件的結構和內容
- 一般XML解析器分為兩種基本類型
- 樹狀解析器(Tree-based parser): XML文件轉換成樹狀結構. 這類解析器 分析整篇文章, 同時提供一個API來訪問所產生樹的每個元素. 其通用 的標準為DOM(文件物件模式)
- 事件解析器(Event-based parser): 將XML文件視為一系列的事件來handler. 當一個特殊事件發生時, 解析器將透過程式所提供的函數來處理.
- 樹狀解析器(Tree-based parser): XML文件轉換成樹狀結構. 這類解析器 分析整篇文章, 同時提供一個API來訪問所產生樹的每個元素. 其通用 的標準為DOM(文件物件模式)
- 事件解析器 有一個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;
}