$title

We are going to parse an XML sample file and print the data to stdout.

Like all examples we start by including Eina:

#include <Eina.h>

We declare 2 booleans to keep track of tags:

Eina_Bool tag_login = EINA_FALSE;
Eina_Bool tag_message = EINA_FALSE;

Here we declare some variables and initialize eina:

int
main(void)
{
FILE *file;
long size;
char *buffer;
Eina_Array *array;
eina_init();

We fill buffer with the XML data from chat.xml:

if ((file = fopen("chat.xml", "rb")))
{
fseek(file, 0, SEEK_END);
size = ftell(file);
fseek(file, 0, SEEK_SET);
if ((buffer = malloc(size)))
{
fread(buffer, 1, size, file);

We will use an Eina_Array to store the data:

array = eina_array_new(10);

Here we call eina_simple_xml_parse(). We pass the buffer with data, its size, we ask to strip leading and trailing whitespace, we give the callback function and the array to store the formatted data:

eina_simple_xml_parse(buffer, size, EINA_TRUE,
_xml_tag_cb, array);

This will loop over the array and print the data using _print callback:

eina_array_foreach(array, _print, NULL);

This is the main XML parser callback, it will check for known tags and get the corresponding values:

static Eina_Bool
_xml_tag_cb(void *data, Eina_Simple_XML_Type type, const char *content,
unsigned offset EINA_UNUSED, unsigned length)
{
char buffer[length+1];
Eina_Array *array = data;
char str[512];

We first check for opening tag:

if (type == EINA_SIMPLE_XML_OPEN)

If we know the tag should have attributes, then we find them using eina_simple_xml_tag_attributes_find() and give them to another parsing function using eina_simple_xml_attributes_parse():

{
if(!strncmp("post", content, strlen("post")))
{
const char *tags = eina_simple_xml_tag_attributes_find(content,
length);
eina_simple_xml_attributes_parse(tags, length - (tags - content),
_xml_attr_cb, str);

We check for other known tags:

}
else if (!strncmp("login>", content, strlen("login>")))
{
tag_login = EINA_TRUE;
}
else if (!strncmp("message>", content, strlen("message>")))
{
tag_message = EINA_TRUE;

We then check data for corresponding tag:

}
}
else if (type == EINA_SIMPLE_XML_DATA)
{
if (tag_login == EINA_TRUE)
{
snprintf(buffer, sizeof(buffer), content);
strncat(str, "<", 1);
strncat(str, buffer, sizeof(buffer));
strncat(str, "> ", 2);
tag_login = EINA_FALSE;

We are doing the formatting in same time and put all the <post> children in str.

}
else if (tag_message == EINA_TRUE)
{
snprintf(buffer, sizeof(buffer), content);
strncat(str, buffer, sizeof(buffer));
tag_message = EINA_FALSE;

Finally, we store our string in the array:

eina_array_push(array, strdup(str));

This is the callback to parse the attributes, we check for key name and keep the value:

static Eina_Bool
_xml_attr_cb(void *data, const char *key, const char *value)
{
char *str = data;
if(!strcmp("id", key))
{
snprintf(str, sizeof(value) + 3, "(%s) ", value);

This is the function that simply print items of the array:

}
return EINA_TRUE;

You can see the full source code here.