我已经搜索了如何使用Expat库解析XML文件,但没有发现对初学者有用。
我想要的只是从配置文件中读取三个数字6,7和8。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<board_height> 6 </board_height>
<board_width> 7 </board_width>
<maximum_highscores> 8 </maximum_highscores>
</Configuration>
答案 0 :(得分:2)
Expat是一个流式 XML解析器。因此,它以块的形式解析文档,由您(程序员)来维护状态,监视进度并捕获解析后所需的数据,而不是之后的数据。
您需要构建三个主要处理程序:
XML_StartElementHandler
XML_EndElementHandler
XML_CharacterDataHandler
您可以在expat.h
中找到这些功能的签名。找到起始标记(<tag>
)时调用第一个函数,第二个函数是找到结束标记(</tag>
),第三个函数捕获标记之间的文本。这是一种基本但快速的解析技术。
这是使用Expat 2.1的概念证明:
#include <expat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef XML_LARGE_SIZE
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
#define XML_FMT_INT_MOD "I64"
#else
#define XML_FMT_INT_MOD "ll"
#endif
#else
#define XML_FMT_INT_MOD "l"
#endif
struct setting {
const char *key;
char *value;
} config[] = {
{"board_height", NULL}, {"board_width", NULL}, {"maximum_highscores", NULL}
};
struct setting *current_setting;
int
key_cmp(void const *ld, void const *rd)
{
struct setting const *const l = ld;
struct setting const *const r = rd;
return strcmp(l->key, r->key);
}
void XMLCALL
handler(void *userData, const XML_Char *s, int len)
{
if(len == 0){
return;
}
if(!current_setting){
return;
}
char *value = malloc((len+1) * sizeof(XML_Char));
strncpy(value, s, len);
current_setting->value = value;
}
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
struct setting key = { .key = name };
current_setting = bsearch(&key, config, sizeof(config)/sizeof(config[0]), sizeof(config[0]), key_cmp);
}
static void XMLCALL
endElement(void *userData, const char *name)
{
current_setting = NULL;
}
int
main(int argc, char *argv[])
{
char buf[BUFSIZ];
XML_Parser parser = XML_ParserCreate(NULL);
int done;
int depth = 0;
XML_SetUserData(parser, &depth);
XML_SetElementHandler(parser, startElement, endElement);
XML_SetCharacterDataHandler(parser, handler);
FILE *fp = fopen("config.xml", "r");
do {
int len = (int)fread(buf, 1, sizeof(buf), fp);
done = len < sizeof(buf);
if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
fprintf(stderr,
"%s at line %" XML_FMT_INT_MOD "u\n",
XML_ErrorString(XML_GetErrorCode(parser)),
XML_GetCurrentLineNumber(parser));
return 1;
}
} while (!done);
XML_ParserFree(parser);
int i;
for (i = 0; i < (sizeof(config)/sizeof(config[0])); i++) {
struct setting current = config[i];
printf("%s: %s\n", current.key, current.value);
free(current.value);
}
return 0;
}
该程序打开一个文件config.xml
进行读取,设置相应的Expat处理程序,并复制它找到的“value”字符串(假设该键是XML标记)。
提供的代码仅仅是一个例子。我不是一名专业的C程序员。