I wanted to write an XML parser for one of my personal projects, and I needed to use Apache APR for this. Since I did not find any example about doing this on the web I thought it might be a good idea to write a short tutorial about this. Maybe it could be helpful to someone else.
Let’s prepare the tutorial, we need a XML file, for example this one example.xml :
<?xml version="1.0" encoding="utf-8"?>
<document>
<a someattribute="attribute of A">
<b>the value of B</b>
</a>
</document>
And a Makefile, for example this one :
APR_CONFIG=$(shell which apr-1-config)
CC=gcc
CXX=g++
CFLAGS=$(shell ${APR_CONFIG} --cflags --cppflags --includes) -Wall
CXXFLAGS=$(shell ${APR_CONFIG} --cflags --cppflags --includes) -Wall
LDFLAGS=$(shell ${APR_CONFIG} --ldflags)
LDLIBS=$(shell ${APR_CONFIG} --libs --link-ld) -laprutil-1
Now the parser, parse.c:
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
/**
* Dumps an XML document
*/
static void dump_xml( apr_xml_elem *e, apr_pool_t *pool )
{
apr_xml_elem *child_element;
const char *text;
if ( e->attr )
{
printf( "This tag has an attribute : <%s %s=%s>\n", e->name, e->attr->name, e->attr->value );
}
if (e->first_child)
{
child_element = e->first_child;
while (child_element)
{
printf( "<%s> --> ", child_element->name );
if( !APR_XML_ELEM_IS_EMPTY( child_element ) )
{
apr_xml_to_text( pool, child_element, APR_XML_X2T_INNER, NULL, NULL, &text, NULL);
printf( "%s\n", text );
}
dump_xml( child_element, pool );
child_element = child_element->next;
}
}
}
/**
* Process an XML file
* @return APR_SUCCESS if success, otherwise -1
*/
static int process_xml_file( const char *filename, apr_pool_t *pool )
{
apr_file_t *fp;
apr_status_t rv;
apr_xml_parser *parser;
apr_xml_doc *doc;
char *errbuf;
if ( ( rv = apr_file_open( &fp, filename, APR_FOPEN_READ, APR_OS_DEFAULT, pool ) ) != APR_SUCCESS ) {
return -1;
}
rv = apr_xml_parse_file( pool, &parser, &doc, fp, 2000 );
if( rv != APR_SUCCESS )
{
printf( "Error : %s", apr_xml_parser_geterror( parser, errbuf, 255 ) );
return -1;
}
dump_xml( doc->root, pool );
return APR_SUCCESS;
}
int main(int argc, char **argv)
{
apr_pool_t *pool;
const char *filename;
if ( argc == 2 )
{
filename = argv[1];
}
else
{
filename = "example.xml";
}
apr_initialize();
apr_pool_create( &pool, NULL );
process_xml_file( filename, pool );
apr_terminate();
return 0;
}
Now store example.xml and parse.c in the same directory and build parse.c
make parse && ./parse filename.xml
You should get the following result:
<a> -->
<b>the value of B</b>
This tag has an attribute : <a someattribute=attribute of A>
<b> --> the value of B
Some useful documentation :
You can dowload the files here












