[libgdata] Bug 584417 – Strings are not properly formed for localisation



commit e74940e22180cdd8cedd79270c118991d3e96c87
Author: Philip Withnall <philip tecnocode co uk>
Date:   Wed Jun 3 13:39:48 2009 +0100

    Bug 584417 â?? Strings are not properly formed for localisation
    
    Reworded a number of strings to make them (hopefully) easier to translate, and
    added translator comments to every string which takes parameters. Moved a few
    existing translator comments so gettext actually picks them up.
    Closes: bgo#584417
---
 gdata/gdata-access-rule.c                         |    4 +-
 gdata/gdata-entry.c                               |    6 +-
 gdata/gdata-feed.c                                |   28 ++--
 gdata/gdata-parsable.c                            |    2 +
 gdata/gdata-parser.c                              |  154 ++++++++++++++-------
 gdata/gdata-private.h                             |   13 +-
 gdata/gdata-service.c                             |   17 ++-
 gdata/services/calendar/gdata-calendar-calendar.c |   30 ++--
 gdata/services/calendar/gdata-calendar-event.c    |   24 ++--
 gdata/services/calendar/gdata-calendar-feed.c     |    4 +-
 gdata/services/contacts/gdata-contacts-contact.c  |   33 ++---
 gdata/services/youtube/gdata-youtube-service.c    |   16 +-
 gdata/services/youtube/gdata-youtube-video.c      |   39 +++---
 13 files changed, 220 insertions(+), 150 deletions(-)

diff --git a/gdata/gdata-access-rule.c b/gdata/gdata-access-rule.c
index a979477..2df4fe5 100644
--- a/gdata/gdata-access-rule.c
+++ b/gdata/gdata-access-rule.c
@@ -240,7 +240,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* gAcl:role */
 		xmlChar *role = xmlGetProp (node, (xmlChar*) "value");
 		if (role == NULL)
-			return gdata_parser_error_required_property_missing ("gAcl:role", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_access_rule_set_role (self, (gchar*) role);
 		xmlFree (role);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "scope") == 0) {
@@ -249,7 +249,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		scope_type = xmlGetProp (node, (xmlChar*) "type");
 		if (scope_type == NULL)
-			return gdata_parser_error_required_property_missing ("gAcl:scope", "type", error);
+			return gdata_parser_error_required_property_missing (node, "type", error);
 
 		scope_value = xmlGetProp (node, (xmlChar*) "value");
 		gdata_access_rule_set_scope (self, (gchar*) scope_type, (gchar*) scope_value);
diff --git a/gdata/gdata-entry.c b/gdata/gdata-entry.c
index 5b14a34..880438f 100644
--- a/gdata/gdata-entry.c
+++ b/gdata/gdata-entry.c
@@ -263,7 +263,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		updated = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) updated, &(self->priv->updated)) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("updated", "entry", (gchar*) updated, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) updated, error);
 			xmlFree (updated);
 			return FALSE;
 		}
@@ -275,7 +275,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		published = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) published, &(self->priv->published)) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("published", "entry", (gchar*) published, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) published, error);
 			xmlFree (published);
 			return FALSE;
 		}
@@ -344,7 +344,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			} else if (xmlStrcmp (author_node->name, (xmlChar*) "email") == 0) {
 				email = xmlNodeListGetString (doc, author_node->children, TRUE);
 			} else {
-				gdata_parser_error_unhandled_element ((gchar*) author_node->ns->prefix, (gchar*) author_node->name, "author", error);
+				gdata_parser_error_unhandled_element (author_node, error);
 				xmlFree (name);
 				xmlFree (uri);
 				xmlFree (email);
diff --git a/gdata/gdata-feed.c b/gdata/gdata-feed.c
index 214aa13..260e248 100644
--- a/gdata/gdata-feed.c
+++ b/gdata/gdata-feed.c
@@ -407,19 +407,19 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 	} else if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
 		/* atom:title */
 		if (self->priv->title != NULL)
-			return gdata_parser_error_duplicate_element ("title", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		self->priv->title = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "subtitle") == 0) {
 		/* atom:subtitle */
 		if (self->priv->subtitle != NULL)
-			return gdata_parser_error_duplicate_element ("subtitle", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		self->priv->subtitle = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0) {
 		/* atom:id */
 		if (self->priv->id != NULL)
-			return gdata_parser_error_duplicate_element ("id", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		self->priv->id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "updated") == 0) {
@@ -428,12 +428,12 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		/* Duplicate checking */
 		if (self->priv->updated.tv_sec != 0 || self->priv->updated.tv_usec != 0)
-			return gdata_parser_error_duplicate_element ("updated", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		/* Parse the string */
 		updated_string = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) updated_string, &(self->priv->updated)) == FALSE) {
-			gdata_parser_error_not_iso8601_format ("updated", "feed", (gchar*) updated_string, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) updated_string, error);
 			xmlFree (updated_string);
 			return FALSE;
 		}
@@ -457,7 +457,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 	} else if (xmlStrcmp (node->name, (xmlChar*) "logo") == 0) {
 		/* atom:logo */
 		if (self->priv->logo != NULL)
-			return gdata_parser_error_duplicate_element ("logo", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		self->priv->logo = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "link") == 0) {
@@ -502,7 +502,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			} else if (xmlStrcmp (author_node->name, (xmlChar*) "email") == 0) {
 				email = xmlNodeListGetString (doc, author_node->children, TRUE);
 			} else {
-				gdata_parser_error_unhandled_element ((gchar*) author_node->ns->prefix, (gchar*) author_node->name, "author", error);
+				gdata_parser_error_unhandled_element (author_node, error);
 				xmlFree (name);
 				xmlFree (uri);
 				xmlFree (email);
@@ -524,7 +524,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		/* Duplicate checking */
 		if (self->priv->generator != NULL)
-			return gdata_parser_error_duplicate_element ("generator", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		/* Parse the element's parameters */
 		name = xmlNodeListGetString (doc, node->children, TRUE);
@@ -542,12 +542,12 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		/* Duplicate checking */
 		if (self->priv->total_results != 0)
-			return gdata_parser_error_duplicate_element ("totalResults", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		/* Parse the number */
 		total_results_string = xmlNodeListGetString (doc, node->children, TRUE);
 		if (total_results_string == NULL)
-			return gdata_parser_error_required_content_missing ("openSearch:totalResults", error);
+			return gdata_parser_error_required_content_missing (node, error);
 
 		self->priv->total_results = strtoul ((gchar*) total_results_string, NULL, 10);
 		xmlFree (total_results_string);
@@ -557,12 +557,12 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		/* Duplicate checking */
 		if (self->priv->start_index != 0)
-			return gdata_parser_error_duplicate_element ("startIndex", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		/* Parse the number */
 		start_index_string = xmlNodeListGetString (doc, node->children, TRUE);
 		if (start_index_string == NULL)
-			return gdata_parser_error_required_content_missing ("openSearch:startIndex", error);
+			return gdata_parser_error_required_content_missing (node, error);
 
 		self->priv->start_index = strtoul ((gchar*) start_index_string, NULL, 10);
 		xmlFree (start_index_string);
@@ -572,12 +572,12 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		/* Duplicate checking */
 		if (self->priv->items_per_page != 0)
-			return gdata_parser_error_duplicate_element ("itemsPerPage", "feed", error);
+			return gdata_parser_error_duplicate_element (node, error);
 
 		/* Parse the number */
 		items_per_page_string = xmlNodeListGetString (doc, node->children, TRUE);
 		if (items_per_page_string == NULL)
-			return gdata_parser_error_required_content_missing ("openSearch:itemsPerPage", error);
+			return gdata_parser_error_required_content_missing (node, error);
 
 		self->priv->items_per_page = strtoul ((gchar*) items_per_page_string, NULL, 10);
 		xmlFree (items_per_page_string);
diff --git a/gdata/gdata-parsable.c b/gdata/gdata-parsable.c
index 7d6ac47..05cc6ec 100644
--- a/gdata/gdata-parsable.c
+++ b/gdata/gdata-parsable.c
@@ -125,6 +125,7 @@ _gdata_parsable_new_from_xml (GType parsable_type, const gchar *first_element, c
 	if (doc == NULL) {
 		xmlError *xml_error = xmlGetLastError ();
 		g_set_error (error, GDATA_PARSER_ERROR, GDATA_PARSER_ERROR_PARSING_STRING,
+			     /* Translators: the parameter is an error message */
 			     _("Error parsing XML: %s"),
 			     xml_error->message);
 		return NULL;
@@ -137,6 +138,7 @@ _gdata_parsable_new_from_xml (GType parsable_type, const gchar *first_element, c
 		xmlFreeDoc (doc);
 		g_set_error (error, GDATA_PARSER_ERROR, GDATA_PARSER_ERROR_EMPTY_DOCUMENT,
 			     _("Error parsing XML: %s"),
+			     /* Translators: this is a dummy error message to be substituted into "Error parsing XML: %s". */
 			     _("Empty document."));
 		return NULL;
 	}
diff --git a/gdata/gdata-parser.c b/gdata/gdata-parser.c
index 1a26a23..f5059f9 100644
--- a/gdata/gdata-parser.c
+++ b/gdata/gdata-parser.c
@@ -22,6 +22,7 @@
 #include <glib/gi18n-lib.h>
 #include <sys/time.h>
 #include <time.h>
+#include <libxml/parser.h>
 
 #include "gdata-service.h"
 #include "gdata-parser.h"
@@ -33,89 +34,148 @@ gdata_parser_error_quark (void)
 	return g_quark_from_static_string ("gdata-parser-error-quark");
 }
 
-gboolean
-gdata_parser_error_required_content_missing (const gchar *element_name, GError **error)
+static gchar *
+print_element (xmlNode *node)
 {
-	/* Translators: the parameter is the name of an XML element.
-	 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names. */
-	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-		     _("A <%s> element was missing required content."),
-		     element_name);
-	return FALSE;
+	gboolean node_has_ns = (node->ns == NULL || node->ns->prefix == NULL ||
+				xmlStrcmp (node->ns->href, (xmlChar*) "http://www.w3.org/2005/Atom";) == 0) ? FALSE : TRUE;
+
+	if (node->parent == NULL) {
+		/* No parent node */
+		if (node_has_ns == TRUE)
+			return g_strdup_printf ("<%s:%s>", node->ns->prefix, node->name);
+		else
+			return g_strdup_printf ("<%s>", node->name);
+	} else {
+		/* We have a parent node, which makes things a lot more complex */
+		gboolean parent_has_ns = (node->parent->ns == NULL || node->parent->ns->prefix == NULL ||
+					  xmlStrcmp (node->parent->ns->href, (xmlChar*) "http://www.w3.org/2005/Atom";) == 0) ? FALSE : TRUE;
+
+		if (parent_has_ns == TRUE && node_has_ns == TRUE)
+			return g_strdup_printf ("<%s:%s/%s:%s>", node->parent->ns->prefix, node->parent->name, node->ns->prefix, node->name);
+		else if (parent_has_ns == FALSE && node_has_ns == TRUE)
+			return g_strdup_printf ("<%s/%s:%s>", node->parent->name, node->ns->prefix, node->name);
+		else
+			return g_strdup_printf ("<%s/%s>", node->parent->name, node->name);
+	}
 }
 
 gboolean
-gdata_parser_error_not_iso8601_format (const gchar *element_name, const gchar *parent_element_name, const gchar *actual_value, GError **error)
+gdata_parser_error_required_content_missing (xmlNode *element, GError **error)
 {
-	/* Translators: the first parameter is the name of an XML element, the second parameter is the name of
-	 * another XML element which is owned by (possessive) the first parameter, and the third parameter is
-	 * the erroneous value (which was not in ISO 8601 format).
-	 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names.
+	gchar *element_string = print_element (element);
+
+	/* Translators: the parameter is the name of an XML element, including the angle brackets ("<" and ">").
 	 *
 	 * For example:
-	 *  A <media:group>'s <uploaded> element content ("2009-05-06 26:30Z") was not in ISO 8601 format. */
+	 *  A <title> element was missing required content. */
+	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR, _("A %s element was missing required content."), element_string);
+	g_free (element_string);
+
+	return FALSE;
+}
+
+gboolean
+gdata_parser_error_not_iso8601_format (xmlNode *element, const gchar *actual_value, GError **error)
+{
+	gchar *element_string = print_element (element);
 	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-		     _("A <%s>'s <%s> element content (\"%s\") was not in ISO 8601 format."),
-		     parent_element_name, element_name, actual_value);
+		     /* Translators: the first parameter is the name of an XML element (including the angle brackets ("<" and ">")), and the second parameter is
+		      * the erroneous value (which was not in ISO 8601 format).
+		      *
+		      * For example:
+		      *  The content of a <media:group/media:uploaded> element ("2009-05-06 26:30Z") was not in ISO 8601 format. */
+		     _("The content of a %s element (\"%s\") was not in ISO 8601 format."), element_string, actual_value);
+	g_free (element_string);
+
 	return FALSE;
 }
 
 gboolean
-gdata_parser_error_unhandled_element (const gchar *element_namespace, const gchar *element_name, const gchar *parent_element_name, GError **error)
+gdata_parser_error_unhandled_element (xmlNode *element, GError **error)
 {
-	/* Translators: the first parameter is the name of an XML namespace, the second the name of an XML element, and the third the
-	 * name of the XML parent element.
-	 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names. */
-	g_set_error (error, GDATA_PARSER_ERROR, GDATA_PARSER_ERROR_UNHANDLED_XML_ELEMENT,
-		     _("Unhandled <%s:%s> element as a child of <%s>."),
-		     element_namespace, element_name, parent_element_name);
+	gchar *element_string = print_element (element);
+
+	/* Translators: the parameter is the name of an XML element, including the angle brackets ("<" and ">").
+	 *
+	 * For example:
+	 *  Unhandled <entry/yt:aspectRatio> element. */
+	g_set_error (error, GDATA_PARSER_ERROR, GDATA_PARSER_ERROR_UNHANDLED_XML_ELEMENT, _("Unhandled %s element."), element_string);
+	g_free (element_string);
+
 	return FALSE;
 }
 
 gboolean
-gdata_parser_error_unknown_property_value (const gchar *element_name, const gchar *property_name, const gchar *actual_value, GError **error)
+gdata_parser_error_unknown_property_value (xmlNode *element, const gchar *property_name, const gchar *actual_value, GError **error)
 {
-	/* Translators: the first parameter is an unknown value, the second is the name of an XML element, and the third is
-	 * the name of an XML property.
-	 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names. Similarly, do not translate (or remove)
-	 * the "@" from before the third parameter. */
+	gchar *property_string, *element_string;
+
+	property_string = g_strdup_printf ("@%s", property_name);
+	element_string = print_element (element);
+
 	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-		     _("Unknown value \"%s\" of a <%s> @%s property."),
-		     actual_value, element_name, property_name);
+		     /* Translators: the first parameter is the name of an XML property, the second is the name of an XML element
+		      * (including the angle brackets ("<" and ">")) to which the property belongs, and the third is the unknown value.
+		      *
+		      * For example:
+		      *  The value of the @time property of a <media:group/media:thumbnail> element ("00:01:42.500") was unknown. */
+		     _("The value of the %s property of a %s element (\"%s\") was unknown."), property_string, element_string, actual_value);
+	g_free (property_string);
+	g_free (element_string);
+
 	return FALSE;
 }
 
 gboolean
-gdata_parser_error_required_property_missing (const gchar *element_name, const gchar *property_name, GError **error)
+gdata_parser_error_required_property_missing (xmlNode *element, const gchar *property_name, GError **error)
 {
-	/* Translators: the first parameter is the name of an XML property, and the second is the name of an XML element.
-	 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names. Similarly, do not translate (or remove)
-	 * the "@" from before the first parameter. */
+	gchar *property_string, *element_string;
+
+	property_string = g_strdup_printf ("@%s", property_name);
+	element_string = print_element (element);
+
 	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-		     _("A required @%s property of a <%s> was not present."),
-		     property_name, element_name);
+		     /* Translators: the first parameter is the name of an XML element (including the angle brackets ("<" and ">")),
+		      * and the second is the name of an XML property which it should have contained.
+		      *
+		      * For example:
+		      *  A required property of a <entry/gAcl:role> element (@value) was not present. */
+		     _("A required property of a %s element (%s) was not present."), property_string, element_string);
+	g_free (property_string);
+	g_free (element_string);
+
 	return FALSE;
 }
 
 gboolean
 gdata_parser_error_required_element_missing (const gchar *element_name, const gchar *parent_element_name, GError **error)
 {
-	/* Translators: the first parameter is the name of an XML element, and the second is the name of the XML parent element.
-	 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names. */
-	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-		     _("A required <%s> element as a child of <%s> was not present."),
-		     element_name, parent_element_name);
+	/* NOTE: This can't take an xmlNode, since such a node wouldn't exist. */
+	gchar *element_string = g_strdup_printf ("<%s/%s>", parent_element_name, element_name);
+
+	/* Translators: the parameter is the name of an XML element, including the angle brackets ("<" and ">").
+	 *
+	 * For example:
+	 *  A required element (<entry/title>) was not present. */
+	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR, _("A required element (%s) was not present."), element_string);
+	g_free (element_string);
+
 	return FALSE;
 }
 
 gboolean
-gdata_parser_error_duplicate_element (const gchar *element_name, const gchar *parent_element_name, GError **error)
+gdata_parser_error_duplicate_element (xmlNode *element, GError **error)
 {
-	/* Translators: the first parameter is the name of an XML element, and the second is the name of the XML parent element.
-	 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names. */
-	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-		     _("A <%s> element as a child of <%s> was duplicated."),
-		     element_name, parent_element_name);
+	gchar *element_string = print_element (element);
+
+	/* Translators: the parameter is the name of an XML element, including the angle brackets ("<" and ">").
+	 *
+	 * For example:
+	 *  A singleton element (<feed/title>) was duplicated. */
+	g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR, _("A singleton element (%s) was duplicated."), element_string);
+	g_free (element_string);
+
 	return FALSE;
 }
 
diff --git a/gdata/gdata-private.h b/gdata/gdata-private.h
index edc9c84..290b70b 100644
--- a/gdata/gdata-private.h
+++ b/gdata/gdata-private.h
@@ -52,14 +52,13 @@ GDataFeed *_gdata_feed_new_from_xml (GType feed_type, const gchar *xml, gint len
 GDataEntry *_gdata_entry_new_from_xml (GType entry_type, const gchar *xml, gint length, GError **error) G_GNUC_WARN_UNUSED_RESULT;
 
 #include "gdata-parser.h"
-gboolean gdata_parser_error_required_content_missing (const gchar *element_name, GError **error);
-gboolean gdata_parser_error_not_iso8601_format (const gchar *element_name, const gchar *parent_element_name, const gchar *actual_value, GError **error);
-gboolean gdata_parser_error_unhandled_element (const gchar *element_namespace, const gchar *element_name,
-					       const gchar *parent_element_name, GError **error);
-gboolean gdata_parser_error_unknown_property_value (const gchar *element_name, const gchar *property_name, const gchar *actual_value, GError **error);
-gboolean gdata_parser_error_required_property_missing (const gchar *element_name, const gchar *property_name, GError **error);
+gboolean gdata_parser_error_required_content_missing (xmlNode *element, GError **error);
+gboolean gdata_parser_error_not_iso8601_format (xmlNode *element, const gchar *actual_value, GError **error);
+gboolean gdata_parser_error_unhandled_element (xmlNode *element, GError **error);
+gboolean gdata_parser_error_unknown_property_value (xmlNode *element, const gchar *property_name, const gchar *actual_value, GError **error);
+gboolean gdata_parser_error_required_property_missing (xmlNode *element, const gchar *property_name, GError **error);
 gboolean gdata_parser_error_required_element_missing (const gchar *element_name, const gchar *parent_element_name, GError **error);
-gboolean gdata_parser_error_duplicate_element (const gchar *element_name, const gchar *parent_element_name, GError **error);
+gboolean gdata_parser_error_duplicate_element (xmlNode *element, GError **error);
 gboolean gdata_parser_time_val_from_date (const gchar *date, GTimeVal *_time);
 gchar *gdata_parser_date_from_time_val (GTimeVal *_time) G_GNUC_WARN_UNUSED_RESULT;
 
diff --git a/gdata/gdata-service.c b/gdata/gdata-service.c
index 64bb5c0..eb978e4 100644
--- a/gdata/gdata-service.c
+++ b/gdata/gdata-service.c
@@ -124,7 +124,7 @@ gdata_service_class_init (GDataServiceClass *klass)
 	 **/
 	g_object_class_install_property (gobject_class, PROP_CLIENT_ID,
 				g_param_spec_string ("client-id",
-					"Client ID", "A client ID for your application (see http://code.google.com/apis/youtube/2.0/developers_guide_protocol_api_query_parameters.html#clientsp).",
+					"Client ID", "A client ID for your application.",
 					NULL,
 					G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
@@ -336,19 +336,23 @@ real_parse_error_response (GDataService *self, GDataServiceError error_type, gui
 	switch (status) {
 		case 400:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+				     /* Translators: the parameter is an error message returned by the server. */
 				     _("Invalid request URI or header, or unsupported nonstandard parameter: %s"), reason_phrase);
 			return;
 		case 401:
 		case 403:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED,
+				     /* Translators: the parameter is an error message returned by the server. */
 				     _("Authentication required: %s"), reason_phrase);
 			return;
 		case 404:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NOT_FOUND,
+				     /* Translators: the parameter is an error message returned by the server. */
 				     _("The requested resource was not found: %s"), reason_phrase);
 			return;
 		case 409:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_CONFLICT,
+				     /* Translators: the parameter is an error message returned by the server. */
 				     _("The entry has been modified since it was downloaded: %s"), reason_phrase);
 			return;
 		case 500:
@@ -361,18 +365,22 @@ real_parse_error_response (GDataService *self, GDataServiceError error_type, gui
 	switch (error_type) {
 		case GDATA_SERVICE_ERROR_WITH_INSERTION:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_WITH_INSERTION,
+				     /* Translators: the first parameter is a HTTP status, and the second is an error message returned by the server. */
 				     _("Error code %u when inserting an entry: %s"), status, reason_phrase);
 			break;
 		case GDATA_SERVICE_ERROR_WITH_UPDATE:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_WITH_UPDATE,
+				     /* Translators: the first parameter is a HTTP status, and the second is an error message returned by the server. */
 				     _("Error code %u when updating an entry: %s"), status, reason_phrase);
 			break;
 		case GDATA_SERVICE_ERROR_WITH_DELETION:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_WITH_DELETION,
+				     /* Translators: the first parameter is a HTTP status, and the second is an error message returned by the server. */
 				     _("Error code %u when deleting an entry: %s"), status, reason_phrase);
 			break;
 		case GDATA_SERVICE_ERROR_WITH_QUERY:
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_WITH_QUERY,
+				     /* Translators: the first parameter is a HTTP status, and the second is an error message returned by the server. */
 				     _("Error code %u when querying: %s"), status, reason_phrase);
 			break;
 		default:
@@ -657,26 +665,32 @@ authenticate (GDataService *self, const gchar *username, const gchar *password,
 
 		if (strncmp (error_start, "NotVerified", error_end - error_start) == 0) {
 			g_set_error (error, GDATA_AUTHENTICATION_ERROR, GDATA_AUTHENTICATION_ERROR_NOT_VERIFIED,
+				     /* Translators: the parameter is a URI for further information. */
 				     _("Your account's e-mail address has not been verified. (%s)"), uri);
 			goto login_error;
 		} else if (strncmp (error_start, "TermsNotAgreed", error_end - error_start) == 0) {
 			g_set_error (error, GDATA_AUTHENTICATION_ERROR, GDATA_AUTHENTICATION_ERROR_TERMS_NOT_AGREED,
+				     /* Translators: the parameter is a URI for further information. */
 				     _("You have not agreed to the service's terms and conditions. (%s)"), uri);
 			goto login_error;
 		} else if (strncmp (error_start, "AccountDeleted", error_end - error_start) == 0) {
 			g_set_error (error, GDATA_AUTHENTICATION_ERROR, GDATA_AUTHENTICATION_ERROR_ACCOUNT_DELETED,
+				     /* Translators: the parameter is a URI for further information. */
 				     _("This account has been deleted. (%s)"), uri);
 			goto login_error;
 		} else if (strncmp (error_start, "AccountDisabled", error_end - error_start) == 0) {
 			g_set_error (error, GDATA_AUTHENTICATION_ERROR, GDATA_AUTHENTICATION_ERROR_ACCOUNT_DISABLED,
+				     /* Translators: the parameter is a URI for further information. */
 				     _("This account has been disabled. (%s)"), uri);
 			goto login_error;
 		} else if (strncmp (error_start, "ServiceDisabled", error_end - error_start) == 0) {
 			g_set_error (error, GDATA_AUTHENTICATION_ERROR, GDATA_AUTHENTICATION_ERROR_SERVICE_DISABLED,
+				     /* Translators: the parameter is a URI for further information. */
 				     _("This account's access to this service has been disabled. (%s)"), uri);
 			goto login_error;
 		} else if (strncmp (error_start, "ServiceUnavailable", error_end - error_start) == 0) {
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_UNAVAILABLE,
+				     /* Translators: the parameter is a URI for further information. */
 				     _("This service is not available at the moment. (%s)"), uri);
 			goto login_error;
 		}
@@ -790,6 +804,7 @@ _gdata_service_send_message (GDataService *self, SoupMessage *message, GError **
 		if (new_uri == NULL) {
 			gchar *uri_string = soup_uri_to_string (new_uri, FALSE);
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+				     /* Translators: the parameter is the URI which is invalid. */
 				     _("Invalid redirect URI: %s"), uri_string);
 			g_free (uri_string);
 			return SOUP_STATUS_NONE;
diff --git a/gdata/services/calendar/gdata-calendar-calendar.c b/gdata/services/calendar/gdata-calendar-calendar.c
index 2c9a28f..e9c72e4 100644
--- a/gdata/services/calendar/gdata-calendar-calendar.c
+++ b/gdata/services/calendar/gdata-calendar-calendar.c
@@ -316,21 +316,21 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* gCal:timezone */
 		xmlChar *_timezone = xmlGetProp (node, (xmlChar*) "value");
 		if (_timezone == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:timezone", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_calendar_set_timezone (self, (gchar*) _timezone);
 		xmlFree (_timezone);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "timesCleaned") == 0) {
 		/* gCal:timesCleaned */
 		xmlChar *times_cleaned = xmlGetProp (node, (xmlChar*) "value");
 		if (times_cleaned == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:timesCleaned", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		self->priv->times_cleaned = strtoul ((gchar*) times_cleaned, NULL, 10);
 		xmlFree (times_cleaned);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "hidden") == 0) {
 		/* gCal:hidden */
 		xmlChar *hidden = xmlGetProp (node, (xmlChar*) "value");
 		if (hidden == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:hidden", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_calendar_set_is_hidden (self, (xmlStrcmp (hidden, (xmlChar*) "true") == 0) ? TRUE : FALSE);
 		xmlFree (hidden);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "color") == 0) {
@@ -340,20 +340,18 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:color", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		if (gdata_color_from_hexadecimal ((gchar*) value, &colour) == FALSE) {
 			/* Error */
-			/* Translators: the first parameter is the name of an XML element, the second parameter is the name of
-			 * another XML element which is owned by (possessive) the first parameter, and the third parameter is
-			 * the erroneous value (which was not in hexadecimal RGB format).
-			 * Do not translate the angle brackets ("<" and ">") â?? they enclose XML element names.
-			 *
-			 * For example:
-			 *  A <entry>'s <gCal:color> element ("00FG56") was not in hexadecimal RGB format. */
 			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-				     _("A <%s>'s <%s> element content (\"%s\") was not in hexadecimal RGB format."),
-				     "entry", "gCal:color", value);
+				     /* Translators: the first parameter is the name of an XML element (including the angle brackets ("<" and ">"),
+				      * and the second parameter is the erroneous value (which was not in hexadecimal RGB format).
+				      *
+				      * For example:
+				      *  The content of a <entry/gCal:color> element ("00FG56") was not in hexadecimal RGB format. */
+				     _("The content of a %s element (\"%s\") was not in hexadecimal RGB format."), "<entry/gCal:color>", value);
 			xmlFree (value);
+
 			return FALSE;
 		}
 
@@ -363,20 +361,20 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* gCal:selected */
 		xmlChar *selected = xmlGetProp (node, (xmlChar*) "value");
 		if (selected == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:selected", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_calendar_set_is_selected (self, (xmlStrcmp (selected, (xmlChar*) "true") == 0) ? TRUE : FALSE);
 		xmlFree (selected);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "accesslevel") == 0) {
 		/* gCal:accesslevel */
 		self->priv->access_level = (gchar*) xmlGetProp (node, (xmlChar*) "value");
 		if (self->priv->access_level == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:accesslevel", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
 		/* app:edited */
 		xmlChar *edited = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) edited, &(self->priv->edited)) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("app:edited", "entry", (gchar*) edited, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) edited, error);
 			xmlFree (edited);
 			return FALSE;
 		}
diff --git a/gdata/services/calendar/gdata-calendar-event.c b/gdata/services/calendar/gdata-calendar-event.c
index c5e24c8..0dda59e 100644
--- a/gdata/services/calendar/gdata-calendar-event.c
+++ b/gdata/services/calendar/gdata-calendar-event.c
@@ -459,7 +459,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		xmlChar *edited = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) edited, &(self->priv->edited)) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("app:edited", "entry", (gchar*) edited, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) edited, error);
 			xmlFree (edited);
 			return FALSE;
 		}
@@ -494,28 +494,28 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* gd:eventStatus */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gd:eventStatus", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_status (self, (gchar*) value);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "visibility") == 0) {
 		/* gd:visibility */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gd:visibility", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_visibility (self, (gchar*) value);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "transparency") == 0) {
 		/* gd:transparency */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gd:transparency", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_transparency (self, (gchar*) value);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "uid") == 0) {
 		/* gCal:uid */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:uid", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_uid (self, (gchar*) value);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "sequence") == 0) {
@@ -525,7 +525,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:sequence", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		else
 			value_uint = strtoul ((gchar*) value, NULL, 10);
 		xmlFree (value);
@@ -544,7 +544,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			is_date = TRUE;
 		} else if (g_time_val_from_iso8601 ((gchar*) start_time, &start_time_timeval) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("gd:when", "entry", (gchar*) start_time, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) start_time, error);
 			xmlFree (start_time);
 			return FALSE;
 		}
@@ -562,7 +562,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 			if (success == FALSE) {
 				/* Error */
-				gdata_parser_error_not_iso8601_format ("gd:when", "entry", (gchar*) end_time, error);
+				gdata_parser_error_not_iso8601_format (node, (gchar*) end_time, error);
 				xmlFree (end_time);
 				return FALSE;
 			}
@@ -580,28 +580,28 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* gCal:guestsCanModify */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:guestsCanModify", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_guests_can_modify (self, (xmlStrcmp (value, (xmlChar*) "true") == 0) ? TRUE : FALSE);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "guestsCanInviteOthers") == 0) {
 		/* gCal:guestsCanInviteOthers */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:guestsCanInviteOthers", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_guests_can_invite_others (self, (xmlStrcmp (value, (xmlChar*) "true") == 0) ? TRUE : FALSE);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "guestsCanSeeGuests") == 0) {
 		/* gCal:guestsCanSeeGuests */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:guestsCanSeeGuests", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_guests_can_see_guests (self, (xmlStrcmp (value, (xmlChar*) "true") == 0) ? TRUE : FALSE);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "anyoneCanAddSelf") == 0) {
 		/* gCal:anyoneCanAddSelf */
 		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:anyoneCanAddSelf", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		gdata_calendar_event_set_anyone_can_add_self (self, (xmlStrcmp (value, (xmlChar*) "true") == 0) ? TRUE : FALSE);
 		xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "who") == 0) {
diff --git a/gdata/services/calendar/gdata-calendar-feed.c b/gdata/services/calendar/gdata-calendar-feed.c
index a11a122..e0bc8f9 100644
--- a/gdata/services/calendar/gdata-calendar-feed.c
+++ b/gdata/services/calendar/gdata-calendar-feed.c
@@ -136,14 +136,14 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* gCal:timezone */
 		xmlChar *_timezone = xmlGetProp (node, (xmlChar*) "value");
 		if (_timezone == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:timezone", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		xmlFree (self->priv->timezone);
 		self->priv->timezone = (gchar*) _timezone;
 	} else if (xmlStrcmp (node->name, (xmlChar*) "timesCleaned") == 0) {
 		/* gCal:timesCleaned */
 		xmlChar *times_cleaned = xmlGetProp (node, (xmlChar*) "value");
 		if (times_cleaned == NULL)
-			return gdata_parser_error_required_property_missing ("gCal:timesCleaned", "value", error);
+			return gdata_parser_error_required_property_missing (node, "value", error);
 		self->priv->times_cleaned = strtoul ((gchar*) times_cleaned, NULL, 10);
 		xmlFree (times_cleaned);
 	} else if (GDATA_PARSABLE_CLASS (gdata_calendar_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
diff --git a/gdata/services/contacts/gdata-contacts-contact.c b/gdata/services/contacts/gdata-contacts-contact.c
index c87b5d1..c5bbc96 100644
--- a/gdata/services/contacts/gdata-contacts-contact.c
+++ b/gdata/services/contacts/gdata-contacts-contact.c
@@ -242,7 +242,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		xmlChar *edited = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) edited, &(self->priv->edited)) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("app:edited", "entry", (gchar*) edited, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) edited, error);
 			xmlFree (edited);
 			return FALSE;
 		}
@@ -255,7 +255,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		address = xmlGetProp (node, (xmlChar*) "address");
 		if (address == NULL)
-			return gdata_parser_error_required_property_missing ("gd:email", "address", error);
+			return gdata_parser_error_required_property_missing (node, "address", error);
 
 		rel = xmlGetProp (node, (xmlChar*) "rel");
 		label = xmlGetProp (node, (xmlChar*) "label");
@@ -270,7 +270,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		else if (xmlStrcmp (primary, (xmlChar*) "true") == 0)
 			primary_bool = TRUE;
 		else {
-			gdata_parser_error_unknown_property_value ("gd:email", "primary", (gchar*) primary, error);
+			gdata_parser_error_unknown_property_value (node, "primary", (gchar*) primary, error);
 			xmlFree (primary);
 			return FALSE;
 		}
@@ -291,7 +291,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		address = xmlGetProp (node, (xmlChar*) "address");
 		if (address == NULL)
-			return gdata_parser_error_required_property_missing ("gd:im", "address", error);
+			return gdata_parser_error_required_property_missing (node, "address", error);
 
 		rel = xmlGetProp (node, (xmlChar*) "rel");
 		label = xmlGetProp (node, (xmlChar*) "label");
@@ -307,7 +307,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		else if (xmlStrcmp (primary, (xmlChar*) "true") == 0)
 			primary_bool = TRUE;
 		else {
-			gdata_parser_error_unknown_property_value ("gd:im", "primary", (gchar*) primary, error);
+			gdata_parser_error_unknown_property_value (node, "primary", (gchar*) primary, error);
 			xmlFree (primary);
 			return FALSE;
 		}
@@ -329,7 +329,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		number = xmlNodeListGetString (doc, node->children, TRUE);
 		if (number == NULL)
-			return gdata_parser_error_required_content_missing ("gd:phoneNumber", error);
+			return gdata_parser_error_required_content_missing (node, error);
 
 		rel = xmlGetProp (node, (xmlChar*) "rel");
 		label = xmlGetProp (node, (xmlChar*) "label");
@@ -345,7 +345,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		else if (xmlStrcmp (primary, (xmlChar*) "true") == 0)
 			primary_bool = TRUE;
 		else {
-			gdata_parser_error_unknown_property_value ("gd:phoneNumber", "primary", (gchar*) primary, error);
+			gdata_parser_error_unknown_property_value (node, "primary", (gchar*) primary, error);
 			xmlFree (primary);
 			return FALSE;
 		}
@@ -367,7 +367,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		address = xmlNodeListGetString (doc, node->children, TRUE);
 		if (address == NULL)
-			return gdata_parser_error_required_content_missing ("gd:postalAddress", error);
+			return gdata_parser_error_required_content_missing (node, error);
 
 		rel = xmlGetProp (node, (xmlChar*) "rel");
 		label = xmlGetProp (node, (xmlChar*) "label");
@@ -382,7 +382,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		else if (xmlStrcmp (primary, (xmlChar*) "true") == 0)
 			primary_bool = TRUE;
 		else {
-			gdata_parser_error_unknown_property_value ("gd:postalAddress", "primary", (gchar*) primary, error);
+			gdata_parser_error_unknown_property_value (node, "primary", (gchar*) primary, error);
 			xmlFree (primary);
 			return FALSE;
 		}
@@ -408,7 +408,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 				if (name != NULL) {
 					xmlFree (name);
 					xmlFree (title);
-					return gdata_parser_error_duplicate_element ("gd:orgName", "gd:organization", error);
+					return gdata_parser_error_duplicate_element (child_node, error);
 				}
 				name = xmlNodeListGetString (doc, child_node->children, TRUE);
 			} else if (xmlStrcmp (child_node->name, (xmlChar*) "orgTitle") == 0) {
@@ -416,13 +416,12 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 				if (title != NULL) {
 					xmlFree (name);
 					xmlFree (title);
-					return gdata_parser_error_duplicate_element ("gd:orgTitle", "gd:organization", error);
+					return gdata_parser_error_duplicate_element (child_node, error);
 				}
 				title = xmlNodeListGetString (doc, child_node->children, TRUE);
 			} else {
 				/* Error */
-				gdata_parser_error_unhandled_element ((gchar*) child_node->ns->prefix, (gchar*) child_node->name,
-								      "gd:organization", error);
+				gdata_parser_error_unhandled_element (child_node, error);
 				xmlFree (name);
 				xmlFree (title);
 				return FALSE;
@@ -442,7 +441,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		else if (xmlStrcmp (primary, (xmlChar*) "true") == 0)
 			primary_bool = TRUE;
 		else {
-			gdata_parser_error_unknown_property_value ("gd:organization", "primary", (gchar*) primary, error);
+			gdata_parser_error_unknown_property_value (node, "primary", (gchar*) primary, error);
 			xmlFree (primary);
 			return FALSE;
 		}
@@ -463,7 +462,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		name = xmlGetProp (node, (xmlChar*) "name");
 		if (name == NULL)
-			return gdata_parser_error_required_property_missing ("gd:extendedProperty", "name", error);
+			return gdata_parser_error_required_property_missing (node, "name", error);
 
 		/* Get either the value property, or the element's content */
 		value = xmlGetProp (node, (xmlChar*) "value");
@@ -486,7 +485,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		href = xmlGetProp (node, (xmlChar*) "href");
 		if (href == NULL)
-			return gdata_parser_error_required_property_missing ("gContact:groupMembershipInfo", "href", error);
+			return gdata_parser_error_required_property_missing (node, "href", error);
 
 		/* Has it been deleted? */
 		deleted = xmlGetProp (node, (xmlChar*) "deleted");
@@ -495,7 +494,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		else if (xmlStrcmp (deleted, (xmlChar*) "true") == 0)
 			deleted_bool = TRUE;
 		else {
-			gdata_parser_error_unknown_property_value ("gContact:groupMembershipInfo", "deleted", (gchar*) deleted, error);
+			gdata_parser_error_unknown_property_value (node, "deleted", (gchar*) deleted, error);
 			xmlFree (deleted);
 			return FALSE;
 		}
diff --git a/gdata/services/youtube/gdata-youtube-service.c b/gdata/services/youtube/gdata-youtube-service.c
index 6e69ba9..8db2405 100644
--- a/gdata/services/youtube/gdata-youtube-service.c
+++ b/gdata/services/youtube/gdata-youtube-service.c
@@ -281,12 +281,10 @@ parse_error_response (GDataService *self, GDataServiceError error_type, guint st
 				location = xmlNodeListGetString (doc, child_node->children, TRUE);
 			else if (xmlStrcmp (child_node->name, (xmlChar*) "internalReason") != 0) {
 				/* Unknown element (ignore internalReason) */
-				if (*error == NULL) {
-					gdata_parser_error_unhandled_element ((gchar*) child_node->ns->prefix, (gchar*) child_node->name,
-									      "error", error);
-				} else {
-					g_warning ("Unhandled <%s:%s> element as a child of <error>.", child_node->ns->prefix, child_node->name);
-				}
+				if (*error == NULL)
+					gdata_parser_error_unhandled_element (child_node, error);
+				else
+					g_warning ("Unhandled <error/%s> element.", child_node->name);
 
 				xmlFree (domain);
 				xmlFree (code);
@@ -317,11 +315,13 @@ parse_error_response (GDataService *self, GDataServiceError error_type, guint st
 						     _("You have made too many API calls recently. Please wait a few minutes and try again."));
 				} else if (xmlStrcmp (code, (xmlChar*) "too_many_entries") == 0) {
 					g_set_error (error, GDATA_YOUTUBE_SERVICE_ERROR, GDATA_YOUTUBE_SERVICE_ERROR_ENTRY_QUOTA_EXCEEDED,
-						     _("You have exceeded your entry quota with the entry \"%s\". "
-						       "Please delete some entries and try again."), location);
+						     _("You have exceeded your entry quota. Please delete some entries and try again."));
 				} else {
 					/* Protocol error */
 					g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+						     /* Translators: the first parameter is an error code, which is a coded string. The second parameter
+						      * is an error domain, which is another coded string. The third parameter is the location of the
+						      * error, which is either a URI or an XPath. */
 						     _("Unknown error code \"%s\" in domain \"%s\" received with location \"%s\"."),
 						     code, domain, location);
 				}
diff --git a/gdata/services/youtube/gdata-youtube-video.c b/gdata/services/youtube/gdata-youtube-video.c
index 0a3b0f4..4b87cf5 100644
--- a/gdata/services/youtube/gdata-youtube-video.c
+++ b/gdata/services/youtube/gdata-youtube-video.c
@@ -656,7 +656,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		else if (xmlStrcmp (is_default, (xmlChar*) "true") == 0)
 			is_default_bool = TRUE;
 		else {
-			gdata_parser_error_unknown_property_value ("media:content", "isDefault", (gchar*) is_default, error);
+			gdata_parser_error_unknown_property_value (node, "isDefault", (gchar*) is_default, error);
 			xmlFree (is_default);
 			return FALSE;
 		}
@@ -671,7 +671,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		else if (xmlStrcmp (expression, (xmlChar*) "nonstop") == 0)
 			expression_enum = GDATA_MEDIA_EXPRESSION_NONSTOP;
 		else {
-			gdata_parser_error_unknown_property_value ("media:content", "expression", (gchar*) expression, error);
+			gdata_parser_error_unknown_property_value (node, "expression", (gchar*) expression, error);
 			xmlFree (expression);
 			return FALSE;
 		}
@@ -704,7 +704,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		/* Check the role property is "uploader" */
 		role = xmlGetProp (node, (xmlChar*) "role");
 		if (xmlStrcmp (role, (xmlChar*) "uploader") != 0) {
-			gdata_parser_error_unknown_property_value ("media:credit", "role", (gchar*) role, error);
+			gdata_parser_error_unknown_property_value (node, "role", (gchar*) role, error);
 			xmlFree (role);
 			return FALSE;
 		}
@@ -713,7 +713,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		/* Check the type property */
 		type = xmlGetProp (node, (xmlChar*) "type");
 		if (type != NULL && xmlStrcmp (type, (xmlChar*) "partner") != 0) {
-			gdata_parser_error_unknown_property_value ("media:credit", "type", (gchar*) type, error);
+			gdata_parser_error_unknown_property_value (node, "type", (gchar*) type, error);
 			xmlFree (type);
 			return FALSE;
 		}
@@ -756,7 +756,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		/* Check the type property is "country" */
 		type = xmlGetProp (node, (xmlChar*) "type");
 		if (xmlStrcmp (type, (xmlChar*) "country") != 0) {
-			gdata_parser_error_unknown_property_value ("media:restriction", "type", (gchar*) type, error);
+			gdata_parser_error_unknown_property_value (node, "type", (gchar*) type, error);
 			xmlFree (type);
 			return FALSE;
 		}
@@ -770,7 +770,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		else if (xmlStrcmp (relationship, (xmlChar*) "deny") == 0)
 			relationship_bool = FALSE;
 		else {
-			gdata_parser_error_unknown_property_value ("media:restriction", "relationship", (gchar*) relationship, error);
+			gdata_parser_error_unknown_property_value (node, "relationship", (gchar*) relationship, error);
 			xmlFree (relationship);
 			return FALSE;
 		}
@@ -789,13 +789,13 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		/* Get the width and height */
 		width = xmlGetProp (node, (xmlChar*) "width");
 		if (width == NULL)
-			return gdata_parser_error_required_property_missing ("media:thumbnail", "width", error);
+			return gdata_parser_error_required_property_missing (node, "width", error);
 		width_uint = strtoul ((gchar*) width, NULL, 10);
 		xmlFree (width);
 
 		height = xmlGetProp (node, (xmlChar*) "height");
 		if (height == NULL)
-			return gdata_parser_error_required_property_missing ("media:thumbnail", "height", error);
+			return gdata_parser_error_required_property_missing (node, "height", error);
 		height_uint = strtoul ((gchar*) height, NULL, 10);
 		xmlFree (height);
 
@@ -806,9 +806,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		} else {
 			time_int = gdata_media_thumbnail_parse_time ((gchar*) _time);
 			if (time_int == -1) {
-				g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-					     _("The @time property (\"%s\") of a <media:thumbnail> could not be parsed."),
-					     (gchar*) _time);
+				gdata_parser_error_unknown_property_value (node, "time", (gchar*) _time, error);
 				xmlFree (_time);
 				return FALSE;
 			}
@@ -823,7 +821,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		/* yt:duration */
 		xmlChar *duration = xmlGetProp (node, (xmlChar*) "seconds");
 		if (duration == NULL)
-			return gdata_parser_error_required_property_missing ("yt:duration", "seconds", error);
+			return gdata_parser_error_required_property_missing (node, "seconds", error);
 
 		self->priv->duration = strtoul ((gchar*) duration, NULL, 10);
 		g_object_notify (G_OBJECT (self), "duration");
@@ -839,7 +837,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		uploaded = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) uploaded, &uploaded_timeval) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("uploaded", "media:group", (gchar*) uploaded, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) uploaded, error);
 			xmlFree (uploaded);
 			return FALSE;
 		}
@@ -855,7 +853,7 @@ parse_media_group_xml_node (GDataYouTubeVideo *self, xmlDoc *doc, xmlNode *node,
 		g_object_notify (G_OBJECT (self), "video-id");
 		xmlFree (video_id);
 	} else {
-		return gdata_parser_error_unhandled_element ((gchar*) node->ns->prefix, (gchar*) node->name, "media:group", error);
+		return gdata_parser_error_unhandled_element (node, error);
 	}
 
 	return TRUE;
@@ -890,11 +888,11 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		min = xmlGetProp (node, (xmlChar*) "min");
 		if (min == NULL)
-			return gdata_parser_error_required_property_missing ("gd:rating", "min", error);
+			return gdata_parser_error_required_property_missing (node, "min", error);
 
 		max = xmlGetProp (node, (xmlChar*) "max");
 		if (max == NULL) {
-			gdata_parser_error_required_property_missing ("gd:rating", "max", error);
+			gdata_parser_error_required_property_missing (node, "max", error);
 			xmlFree (min);
 			return FALSE;
 		}
@@ -953,7 +951,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* View count */
 		view_count = xmlGetProp (node, (xmlChar*) "viewCount");
 		if (view_count == NULL)
-			return gdata_parser_error_required_property_missing ("yt:statistics", "viewCount", error);
+			return gdata_parser_error_required_property_missing (node, "viewCount", error);
 		self->priv->view_count = strtoul ((gchar*) view_count, NULL, 10);
 		g_object_notify (G_OBJECT (self), "view-count");
 		xmlFree (view_count);
@@ -985,7 +983,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		recorded = xmlNodeListGetString (doc, node->children, TRUE);
 		if (gdata_parser_time_val_from_date ((gchar*) recorded, &recorded_timeval) == FALSE) {
 			/* Error */
-			gdata_parser_error_not_iso8601_format ("recorded", "entry", (gchar*) recorded, error);
+			gdata_parser_error_not_iso8601_format (node, (gchar*) recorded, error);
 			xmlFree (recorded);
 			return FALSE;
 		}
@@ -1006,7 +1004,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 				name = xmlGetProp (child_node, (xmlChar*) "name");
 				if (name == NULL)
-					return gdata_parser_error_required_property_missing ("yt:state", "name", error);
+					return gdata_parser_error_required_property_missing (child_node, "name", error);
 
 				message = xmlNodeListGetString (doc, child_node->children, TRUE);
 				reason_code = xmlGetProp (child_node, (xmlChar*) "reasonCode");
@@ -1022,8 +1020,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 				xmlFree (help_uri);
 			} else {
 				/* Unhandled element */
-				return gdata_parser_error_unhandled_element ((gchar*) child_node->ns->prefix,
-									     (gchar*) child_node->name, "app:control", error);
+				return gdata_parser_error_unhandled_element (child_node, error);
 			}
 
 			child_node = child_node->next;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]