expat常用的两个set handler函数:
XML_SetElementHandler(XML_Parser p,
XML_StartElementHandler start,
XML_EndElementHandler end);
XML_SetCharacterDataHandler(XML_Parser p,
XML_CharacterDataHandler hndl);
第一个函数注册了开始元素和结束元素的handle。
第二个函数注册了文本数据的 handle 。
我的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<Marker>
<MarkerName>subtype:caption</MarkerName>
<Parameters>
<Parameter>
<Name>data,en-US</Name>
<Type>String</Type>
<Value> CONTINUE TO PLAY </Value>
</Parameter>
</Parameters>
</Marker>
最后程序的输出为:
$ ./elements < metadata.xml
Marker
MarkerName : subtype:caption
Parameters
Parameter
Name : data,en-US
Type : String
Value : CONTINUE TO PLAY
sample/elements.c
$ cat sample/elements.c
/* This is simple demonstration of how to use expat. This program
reads an XML document from standard input and writes a line with the
name of each element to standard output indenting child elements by
one tab stop more than their parent element. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xmlparse.h"
void startElement(void *userData, const char *name, const char **atts)
{
int i;
int *depthPtr = userData;
for (i = 0; i < *depthPtr; i++)
putchar('\t');
printf("%s", name);
*depthPtr += 1;
}
void endElement(void *userData, const char *name)
{
int *depthPtr = userData;
*depthPtr -= 1;
}
/*
** 在dataHandle里面,len的长度为1,说明text data为空,但是有一个'\n' ,为了输出漂亮点,做了一个处理。
*/
void dataHandle(void *userData, char *s, int len)
{
if (len == 1 && *s == '\n') {
putchar('\n');
return;
}
if (len > 0) {
char *text = malloc(len + 1);
strncpy(text, s, len);
*(text + len)= 0;
printf(" : %s", text);
}
}
int main()
{
char buf[BUFSIZ];
int done;
int depth = 0;
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, &depth);
XML_SetElementHandler(parser, startElement, endElement);
XML_SetCharacterDataHandler(parser, (XML_CharacterDataHandler)dataHandle);
do {
size_t len = fread(buf, 1, sizeof(buf), stdin);
done = len < sizeof(buf);
if (!XML_Parse(parser, buf, len, done)) {
fprintf(stderr,
"%s at line %d\n",
XML_ErrorString(XML_GetErrorCode(parser)),
XML_GetCurrentLineNumber(parser));
return 1;
}
} while (!done);
XML_ParserFree(parser);
return 0;
}
在Linux上编译:
在Linux(ubuntu)下,已经有了Makefile,直接make就可以生成需要的libexpat.a,所以编译sample/elements.c就直接用gcc编译就可以了。
编译sample.c:
gcc -Wall -O2 -Ixmltok -Ixmlparse -DXML_NS -DXML_DTD -o elements sample/elements.c xmlparse/libexpat.a
或者参考xmlwf,直接修改Makefile就可以生成sample程序了:
XMLWF=xmlwf/xmlwf$(EXE)
+ELEMENTS=elements$(EXE)
-all: $(XMLWF)
+all: $(XMLWF)
$(ELEMENTS)
$(XMLWF): $(OBJS) $(LIB)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIB)
+$(ELEMENTS):
+ $(CC) $(CFLAGS) -o $@ sample/elements.c $(LIB)
clean:
- rm -f $(OBJS) $(LIBOBJS) $(LIB) $(XMLWF)
+ rm -f $(OBJS) $(LIBOBJS) $(LIB) $(XMLWF) $(ELEMENTS)