The following example demonstrates a program which goes through an XML document, containing a library of books, some of which are fiction and some of which are non-fiction. If the book has type="fiction", it calls descent_xml_parse_cstr() on a child handler, which then looks for an author element and prints its contents.
#include <libadt/str.h>
#include <descent-xml.h>
#include <stdio.h>
#define str libadt_str_literal
#define lex descent_xml_lex_init
#define eof descent_xml_classifier_eof
#define unexpected descent_xml_classifier_unexpected
#define close descent_xml_classifier_element_close_name
#define error descent_xml_parse_error
#define parse descent_xml_parse_cstr
#define valid descent_xml_validate_document
#define XML \
"<?xml version=\"1.0\" ?>\n" \
"<library>\n" \
" <book type=\"non-fiction\">\n" \
" <title>The Pragmatic Programmer</title>\n" \
" <author>David Thomas</author>\n" \
" <author>Andrew Hunt</author>\n" \
" </book>\n" \
" <book type=\"fiction\">\n" \
" <title>Magician</title>\n" \
" <author>Raymond E. Feist</author>\n" \
" </book>\n" \
" <book type=\"non-fiction\">\n" \
" <title>Operating Systems Principles & Practice Second Edition</title>\n" \
" <author>Thomas Anderson</author>\n" \
" <author>Michael Dahlin</author>\n" \
" </book>\n" \
" <book type=\"fiction\">\n" \
" <title>Stormbreaker</title>\n" \
" <author>Anthony Horowitz</author>\n" \
" </book>\n" \
"</library>"
static int is_end_type(
lex_t token)
{
return token.
type == eof;
}
static int is_error_type(
lex_t token)
{
return token.
type == unexpected
}
static int equal(const char *a, const char *b)
{
return strcmp(a, b) == 0;
}
void text_printer(
char *text,
bool is_cdata,
void *context
)
{
(void)context;
(void)is_cdata;
printf("%s", text);
}
char *element_name,
char **attributes,
bool empty,
void *context
)
{
(void)context;
(void)attributes;
if (!empty && equal(element_name, "author")) {
printf("Author: ");
while (token.
type != close) {
if (is_end_type(token) || is_error_type(token))
return token;
token = parse(token, NULL, text_printer, NULL);
}
printf("\n");
} else if (!empty) {
while (token.
type != close) {
if (is_end_type(token) || is_error_type(token))
return token;
token = parse(token, NULL, NULL, NULL);
}
}
token = parse(token, NULL, NULL, NULL);
return token;
}
char *element_name,
char **attributes,
bool empty,
void *context
)
{
(void)context;
if (empty || !equal(element_name, "book"))
return token;
for (; *attributes; attributes += 2) {
if (
equal(attributes[0], "type")
&& equal(attributes[1], "fiction")
) {
while (token.
type != close) {
if (is_end_type(token) || is_error_type(token))
return token;
token = parse(token, author_handler, NULL, NULL);
}
token = parse(token, NULL, NULL, NULL);
}
}
return token;
}
int main()
{
lex_t token = lex(str(XML));
if (!valid(token))
return 1;
while (!is_end_type(token)) {
if (is_error_type(token)) {
return 1;
}
token = parse(token, book_handler, NULL, NULL);
}
}
Represents a single token.
Definition lex.h:42
descent_xml_classifier_fn * type
Represents the type of token classifiered.
Definition lex.h:46