-
Notifications
You must be signed in to change notification settings - Fork 743
/
c-libxmlsax-count.c
87 lines (71 loc) · 2.04 KB
/
c-libxmlsax-count.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// C implementation, using libxml SAX.
//
// Eli Bendersky [http://eli.thegreenplace.net]
// This code is in the public domain.
#include <libxml/parser.h>
#include <stdio.h>
#include <string.h>
// Traversal state.
typedef struct {
int counter;
int inLocation;
char buf[8192];
} CountState;
void start_document_cb(void* ctx) {
CountState* state = (CountState*)ctx;
state->counter = 0;
state->inLocation = 0;
}
void start_element_cb(void* ctx, const xmlChar* name, const xmlChar** attrs) {
CountState* state = (CountState*)ctx;
if (!strcmp((const char*)name, "location")) {
state->inLocation = 1;
} else {
state->inLocation = 0;
}
}
void end_element_cb(void* ctx, const xmlChar* name) {
CountState* state = (CountState*)ctx;
state->inLocation = 0;
}
void characters_cb(void* ctx, const xmlChar* ch, int len) {
CountState* state = (CountState*)ctx;
if (state->inLocation) {
// ch is not NULL-terminated, so we'll copy it to a temporary
// NULL-terminated buffer stored in 'state'.
if (len + 1 > sizeof(state->buf)) {
fprintf(stderr, "characters too long: %d\n", len);
exit(1);
}
memcpy(state->buf, ch, len);
state->buf[len] = 0;
if (strstr(state->buf, "Africa")) {
state->counter++;
}
}
}
int main(int argc, char** argv) {
if (argc != 2) {
return 1;
}
// Initialize libxml and check for potential ABI mismatches with the shared
// library.
LIBXML_TEST_VERSION
xmlSAXHandler handler = {0};
handler.startDocument = start_document_cb;
handler.startElement = start_element_cb;
handler.endElement = end_element_cb;
handler.characters = characters_cb;
// Start with uninitialized state; it will be initialized by the startDocument
// callback.
CountState count_state;
if (xmlSAXUserParseFile(&handler, &count_state, argv[1]) != 0) {
xmlError* err = xmlGetLastError();
printf("Error parsing %s: line %d, error: %s\n",
argv[1], err->line, err->message);
return 1;
}
printf("count = %d\n", count_state.counter);
xmlCleanupParser();
return 0;
}