* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Created by Quy Tonthat <qtonthat@gmail.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
{
gchar *url_format;
gchar *lat_path;
+ gchar *lat_attr;
gchar *lon_path;
+ gchar *lon_attr;
struct LatLon ll;
};
PROP_URL_FORMAT,
PROP_LAT_PATH,
+ PROP_LAT_ATTR,
PROP_LON_PATH,
+ PROP_LON_ATTR,
};
static void
{
VikGotoXmlTool *self = VIK_GOTO_XML_TOOL (object);
VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
+ gchar **splitted = NULL;
switch (property_id)
{
break;
case PROP_LAT_PATH:
+ splitted = g_strsplit (g_value_get_string (value), "@", 2);
g_free (priv->lat_path);
- priv->lat_path = g_value_dup_string (value);
+ priv->lat_path = splitted[0];
+ if (splitted[1])
+ {
+ g_object_set (object, "lat-attr", splitted[1], NULL);
+ g_free (splitted[1]);
+ }
+ /* only free the tab, not the strings */
+ g_free (splitted);
+ splitted = NULL;
+ break;
+
+ case PROP_LAT_ATTR:
+ /* Avoid to overwrite XPATH value */
+ /* NB: This disable future overwriting,
+ but as property is CONSTRUCT_ONLY there is no matter */
+ if (!priv->lat_attr || g_value_get_string (value))
+ {
+ g_free (priv->lat_attr);
+ priv->lat_attr = g_value_dup_string (value);
+ }
break;
case PROP_LON_PATH:
+ splitted = g_strsplit (g_value_get_string (value), "@", 2);
g_free (priv->lon_path);
- priv->lon_path = g_value_dup_string (value);
+ priv->lon_path = splitted[0];
+ if (splitted[1])
+ {
+ g_object_set (object, "lon-attr", splitted[1], NULL);
+ g_free (splitted[1]);
+ }
+ /* only free the tab, not the strings */
+ g_free (splitted);
+ splitted = NULL;
+ break;
+
+ case PROP_LON_ATTR:
+ /* Avoid to overwrite XPATH value */
+ /* NB: This disable future overwriting,
+ but as property is CONSTRUCT_ONLY there is no matter */
+ if (!priv->lon_attr || g_value_get_string (value))
+ {
+ g_free (priv->lon_attr);
+ priv->lon_attr = g_value_dup_string (value);
+ }
break;
default:
g_value_set_string (value, priv->lat_path);
break;
+ case PROP_LAT_ATTR:
+ g_value_set_string (value, priv->lat_attr);
+ break;
+
case PROP_LON_PATH:
g_value_set_string (value, priv->lon_path);
break;
+ case PROP_LON_ATTR:
+ g_value_set_string (value, priv->lon_attr);
+ break;
+
default:
/* We don't have any other property... */
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
pspec);
pspec = g_param_spec_string ("lat-path",
- "Lat path",
+ "Latitude path",
"XPath of the latitude",
"<no-set>" /* default value */,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
PROP_LAT_PATH,
pspec);
+ pspec = g_param_spec_string ("lat-attr",
+ "Latitude attribute",
+ "XML attribute of the latitude",
+ NULL /* default value */,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class,
+ PROP_LAT_ATTR,
+ pspec);
+
pspec = g_param_spec_string ("lon-path",
- "Lon path",
+ "Longitude path",
"XPath of the longitude",
"<no-set>" /* default value */,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
PROP_LON_PATH,
pspec);
+ pspec = g_param_spec_string ("lon-attr",
+ "Longitude attribute",
+ "XML attribute of the longitude",
+ NULL /* default value */,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class,
+ PROP_LON_ATTR,
+ pspec);
+
parent_class = VIK_GOTO_TOOL_CLASS (klass);
parent_class->get_url_format = _goto_xml_tool_get_url_format;
VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
priv->url_format = NULL;
priv->lat_path = NULL;
+ priv->lat_attr = NULL;
priv->lon_path = NULL;
+ priv->lon_attr = NULL;
//
priv->ll.lat = NAN;
priv->ll.lon = NAN;
return equal;
}
+/* Called for open tags <foo bar="baz"> */
+static void
+_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ VikGotoXmlTool *self = VIK_GOTO_XML_TOOL (user_data);
+ VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
+ const GSList *stack = g_markup_parse_context_get_element_stack (context);
+ /* Longitude */
+ if (priv->lon_attr != NULL && isnan(priv->ll.lon) && stack_is_path (stack, priv->lon_path))
+ {
+ int i=0;
+ while (attribute_names[i] != NULL)
+ {
+ if (strcmp (attribute_names[i], priv->lon_attr) == 0)
+ {
+ priv->ll.lon = g_ascii_strtod(attribute_values[i], NULL);
+ }
+ i++;
+ }
+ }
+ /* Latitude */
+ if (priv->lat_attr != NULL && isnan(priv->ll.lat) && stack_is_path (stack, priv->lat_path))
+ {
+ int i=0;
+ while (attribute_names[i] != NULL)
+ {
+ if (strcmp (attribute_names[i], priv->lat_attr) == 0)
+ {
+ priv->ll.lat = g_ascii_strtod(attribute_values[i], NULL);
+ }
+ i++;
+ }
+ }
+}
+
/* Called for character data */
/* text is not nul-terminated */
static void
const GSList *stack = g_markup_parse_context_get_element_stack (context);
gchar *textl = g_strndup(text, text_len);
/* Store only first result */
- if (isnan(priv->ll.lat) && stack_is_path (stack, priv->lat_path))
+ if (priv->lat_attr == NULL && isnan(priv->ll.lat) && stack_is_path (stack, priv->lat_path))
{
priv->ll.lat = g_ascii_strtod(textl, NULL);
}
- if (isnan(priv->ll.lon) && stack_is_path (stack, priv->lon_path))
+ if (priv->lon_attr == NULL && isnan(priv->ll.lon) && stack_is_path (stack, priv->lon_path))
{
priv->ll.lon = g_ascii_strtod(textl, NULL);
}
_goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll)
{
GMarkupParser xml_parser;
- GMarkupParseContext *xml_context;
- GError *error;
+ GMarkupParseContext *xml_context = NULL;
+ GError *error = NULL;
VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
g_return_val_if_fail(priv != NULL, FALSE);
+ g_debug ("%s: %s@%s, %s@%s",
+ __FUNCTION__,
+ priv->lat_path, priv->lat_attr,
+ priv->lon_path, priv->lon_attr);
+
FILE *file = g_fopen (filename, "r");
if (file == NULL)
/* TODO emit warning */
return FALSE;
/* setup context parse (ie callbacks) */
- xml_parser.start_element = NULL;
+ if (priv->lat_attr != NULL || priv->lon_attr != NULL)
+ // At least one coordinate uses an attribute
+ xml_parser.start_element = &_start_element;
+ else
+ xml_parser.start_element = NULL;
xml_parser.end_element = NULL;
- xml_parser.text = &_text;
+ if (priv->lat_attr == NULL || priv->lon_attr == NULL)
+ // At least one coordinate uses a raw element
+ xml_parser.text = &_text;
+ else
+ xml_parser.text = NULL;
xml_parser.passthrough = NULL;
xml_parser.error = NULL;
gchar buff[BUFSIZ];
size_t nb;
- while ((nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0)
+ while (xml_context &&
+ (nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0)
{
if (!g_markup_parse_context_parse(xml_context, buff, nb, &error))
- fprintf(stderr, "%s: parsing error.\n", __FUNCTION__);
+ {
+ fprintf(stderr, "%s: parsing error: %s.\n",
+ __FUNCTION__, error->message);
+ g_markup_parse_context_free(xml_context);
+ xml_context = NULL;
+ }
+ g_clear_error (&error);
}
/* cleanup */
- if (!g_markup_parse_context_end_parse(xml_context, &error))
- fprintf(stderr, "%s: errors occurred reading file.\n", __FUNCTION__);
+ if (xml_context &&
+ !g_markup_parse_context_end_parse(xml_context, &error))
+ fprintf(stderr, "%s: errors occurred while reading file: %s.\n",
+ __FUNCTION__, error->message);
+ g_clear_error (&error);
- g_markup_parse_context_free(xml_context);
+ if (xml_context)
+ g_markup_parse_context_free(xml_context);
+ xml_context = NULL;
fclose (file);
if (ll != NULL)