Convert user strings to XML queries

Convert user strings to XML queries — How to convert a search string in the user search language to the XML query language

The Program

Leveraging a XesamGUserSearchParser chained up to a XesamGXmlQueryBuilder we will transform a user search string into an XML query.

#include <stdio.h>
#include <glib.h>
#include <glib-object.h>
#include <xesam-glib.h>

int
main (int argc, char *argv[])
{
	XesamGQueryBuilder 		*builder;
	XesamGUserSearchParser	*parser;
	GOptionContext 			*options;
	GError					*error;
	GString					*search;
	gchar					*xml;
	int						i;
	
	g_type_init ();
	
	if (argc == 1) {
		g_printerr ("You must supply at least one search term");
		return 1;
	}
	
	/* Join the users search terms into one string */
	search = g_string_sized_new (512);
	for (i = 1; i < argc; i++) {
		g_string_append (search, " ");
		g_string_append (search, argv[i]);
	}
	
	/* Create parser and builder */
	builder = XESAM_G_QUERY_BUILDER (xesam_g_xml_query_builder_new ());
	parser = xesam_g_user_search_parser_new ();
	
	/* Set parser up to invoke the xml builder */
	xesam_g_user_search_parser_add_builder (parser, builder);
	
	/* Run the parser on the user input. This will automatically trigger the
	 * builder we added to the parser */
	error = NULL;
	xesam_g_user_search_parser_parse_string (parser, search->str, &error);
	
	if (error) {
		g_printerr ("Parse error: %s\n", error->message);
		
		/* Clean up */
		g_error_free (error);
		g_string_free (search, TRUE);
		g_object_unref (parser);
		g_object_unref (builder);
		
		return 2;
	}
	
	/* Get the output from the builder and print it */
	xml = xesam_g_xml_query_builder_get_xml (XESAM_G_XML_QUERY_BUILDER (builder));
	g_printf ("%s\n", xml);
	
	/* Clean up */
	g_free (xml);
	g_string_free (search, TRUE);
	g_object_unref (parser);
	g_object_unref (builder);
	
	return 0;
}

Compilation

Save the code in a file called xesam-query-convert.c and compile it with

gcc $(pkg-config --libs --cflags xesam-glib) xesam-query-convert.c -o xesam-query-convert

Test Run

You can take the compiled program for a test run simple by running

./xesam-query-convert hello world

This will print out the following:

<?xml version="1.0" encoding="utf-8"?><request xmlns="http://freedesktop.org/standards/xesam/1.0/query"><query><fullText negate="false"><string>hello</string></fullText></query></request>

If you want prettier output it is suggested that you pipe the output of the command into xmllint, like so

./xesam-query-convert hello world | xmllint --format -

Note that the trailing dash i important. This will print out as:

<?xml version="1.0" encoding="utf-8"?>
<request xmlns="http://freedesktop.org/standards/xesam/1.0/query">
  <query>
    <fullText negate="false">
      <string>hello</string>
    </fullText>
  </query>
</request>

This command line tool is infact pretty handy if you want to explore the Xesam user search language and the XML query language. You can write more advanced queries like this too:

$ ./xesam-query-convert '"hello world" or "hola mondo"' | xmllint --format -

Should print out:

<?xml version="1.0" encoding="utf-8"?>
<request xmlns="http://freedesktop.org/standards/xesam/1.0/query">
  <query>
    <or>
      <fullText negate="false">
        <string>hello world</string>
      </fullText>
      <fullText negate="false">
        <string>hola mondo</string>
      </fullText>
    </or>
  </query>
</request>