Expat?
Expat은 SAX형 XML파서로 이벤트 기반으로 데이터 처리를 한다. XML 파싱할 때 DOM과 같이 XML 크기와 비례하여 메모리가 증가하지 않아, 메모리 제약이 상대적으로 큰 임베디드 장비에서 사용하기 적합하다. 본 문서는 1553 Framework의 일환으로 개발중인 XML 파서에서 사용된 Expat을 소개하는 것을 목적으로 한다.
더 자세한 DOM과 SAX의 차이는 아래의 표를 참고한다.
구분 | DOM | SAX |
파싱 기반 | 트리 기반 | 이벤트 기반 |
데이터 접근 방식 | 랜덤 | 순차 |
메모리 사용 방식 | 데이터 크기에 비례해서 증가 | 데이터 크기와 상관없이 일정 메모리 사용 |
적합한 데이터 | 경량 데이터 | 경량/대용량 데이터 |
데이터 재사용 | 가능 | 불가능(재파싱해서 사용할 수 있음) |
License
MIT 라이센스를 따르고 있다.
How to Install
본 문서에서 사용된 expat 버전은 2.0.1이다. configure 스크립트가 설치된 시스템에서 expat_config.h 를 생성하여 사용해도 되고, 아래의 expat_config.h를 사용해도 된다. 단, 그대로 가져다 사용하면 안되고, 각자의 시스템에 맞도록 수정을 해야한다.
-
/* expat_config.h. Generated by configure. */
/* expat_config.h.in. Generated from configure.in by autoheader. */
/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
#define BYTEORDER 4321
/* Define to 1 if you have the `bcopy' function. */
#define HAVE_BCOPY 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 0
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 0
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 0
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have a working `mmap' system call. */
#define HAVE_MMAP 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 0
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 0
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "expat-bugs@libexpat.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "expat"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "expat 2.0.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "expat"
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.0.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* whether byteorder is bigendian */
/* #undef WORDS_BIGENDIAN */
/* Define to specify how much context to retain around the current parse
point. */
#define XML_CONTEXT_BYTES 1024
/* Define to make parameter entity parsing functionality available. */
#define XML_DTD 1
/* Define to make XML Namespaces functionality available. */
#define XML_NS 1
/* Define to __FUNCTION__ or "" if `__func__' does not conform to ANSI C. */
/* #undef __func__ */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `long' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */
VxWorks
-DHAVE_EXPAT_CONFIG_H 옵션을 주고 컴파일을 해야하며, DTD 파싱을 원할 경우 -DXML_DTD를 추가하여 컴파일하면 된다.
Windows
윈도우에서도 vxworks 환경과 같이 동일한 옵션을 주고 컴파일을 하면된다.
How to Use
Expat API는 상당히 많으나, 아래의 네 가지 정도 API만 숙지한다면, 기본적인 XML 파싱을 할 수 있을 것이다.
- XML_ParserCreate
- XML_SetElementHandler
- XML_SetCharacterDataHandler
- XML_Parse
아래의 예제는 위의 API를 사용하여, XML를 간단히 파싱하는 것을 보여준다.
Example
References
이 글은 스프링노트에서 작성되었습니다.