[libgdata/libgdata-0-6] [core] Add namespace checks to all parse_xml() functions



commit 3a05c76a9f4d6da5a4b4db95faafa2932ae08265
Author: Philip Withnall <philip tecnocode co uk>
Date:   Wed Mar 24 23:35:49 2010 +0000

    [core] Add namespace checks to all parse_xml() functions
    
    This should (theoretically, though untested) speed up parsing a little, since
    whole chunks of unrelated elements can now be skipped at once in the search
    for the right element.
    
    Important: these changes accidentally fix the behaviour of
    gdata_entry_get_id() for #GDataPicasaWebAlbum, which was returning incorrect
    results before. Any applications which depend on the broken behaviour should
    be updated to deal with the correct form IDs (i.e. URIs), or use a new
    gdata_picasaweb_album_get_id() function which will be added shortly.

 gdata/atom/gdata-author.c                         |   57 ++--
 gdata/exif/gdata-exif-tags.c                      |    3 +
 gdata/gd/gdata-gd-name.c                          |   29 ++-
 gdata/gd/gdata-gd-organization.c                  |    8 +-
 gdata/gd/gdata-gd-postal-address.c                |   29 +-
 gdata/gd/gdata-gd-when.c                          |    8 +-
 gdata/gdata-access-rule.c                         |   63 ++---
 gdata/gdata-entry.c                               |  147 +++++-----
 gdata/gdata-feed.c                                |  301 +++++++++++----------
 gdata/gdata-parser.c                              |   21 ++
 gdata/gdata-parser.h                              |    3 +
 gdata/georss/gdata-georss-where.c                 |    9 +-
 gdata/media/gdata-media-group.c                   |  205 +++++++-------
 gdata/services/calendar/gdata-calendar-calendar.c |  130 +++++-----
 gdata/services/calendar/gdata-calendar-event.c    |  262 +++++++++---------
 gdata/services/calendar/gdata-calendar-feed.c     |    8 +-
 gdata/services/contacts/gdata-contacts-contact.c  |  175 ++++++------
 gdata/services/documents/gdata-documents-entry.c  |   97 ++++----
 gdata/services/documents/gdata-documents-feed.c   |   10 +-
 gdata/services/picasaweb/gdata-picasaweb-album.c  |  191 +++++++-------
 gdata/services/picasaweb/gdata-picasaweb-feed.c   |  107 ++++----
 gdata/services/picasaweb/gdata-picasaweb-file.c   |  191 +++++++-------
 gdata/services/picasaweb/gdata-picasaweb-user.c   |   10 +-
 gdata/services/youtube/gdata-youtube-control.c    |   11 +-
 gdata/services/youtube/gdata-youtube-group.c      |  135 +++++-----
 gdata/services/youtube/gdata-youtube-video.c      |  217 ++++++++-------
 gdata/tests/picasaweb.c                           |    4 +-
 27 files changed, 1250 insertions(+), 1181 deletions(-)
---
diff --git a/gdata/atom/gdata-author.c b/gdata/atom/gdata-author.c
index d214e25..f8216ae 100644
--- a/gdata/atom/gdata-author.c
+++ b/gdata/atom/gdata-author.c
@@ -192,34 +192,37 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataAuthorPrivate *priv = GDATA_AUTHOR (parsable)->priv;
 
-	if (xmlStrcmp (node->name, (xmlChar*) "name") == 0) {
-		/* atom:name */
-		xmlChar *name;
-
-		if (priv->name != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-
-		name = xmlNodeListGetString (doc, node->children, TRUE);
-		if (name == NULL || *name == '\0') {
-			xmlFree (name);
-			return gdata_parser_error_required_content_missing (node, error);
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2005/Atom";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "name") == 0) {
+			/* atom:name */
+			xmlChar *name;
+
+			if (priv->name != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+
+			name = xmlNodeListGetString (doc, node->children, TRUE);
+			if (name == NULL || *name == '\0') {
+				xmlFree (name);
+				return gdata_parser_error_required_content_missing (node, error);
+			}
+			priv->name = (gchar*) name;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "uri") == 0) {
+			/* atom:uri */
+			if (priv->uri != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+
+			priv->uri = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "email") == 0) {
+			/* atom:email */
+			if (priv->email_address != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+
+			priv->email_address = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_author_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-		priv->name = (gchar*) name;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "uri") == 0) {
-		/* atom:uri */
-		if (priv->uri != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-
-		priv->uri = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "email") == 0) {
-		/* atom:email */
-		if (priv->email_address != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-
-		priv->email_address = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (GDATA_PARSABLE_CLASS (gdata_author_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_author_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/exif/gdata-exif-tags.c b/gdata/exif/gdata-exif-tags.c
index 6db0d58..98b3476 100644
--- a/gdata/exif/gdata-exif-tags.c
+++ b/gdata/exif/gdata-exif-tags.c
@@ -108,6 +108,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataExifTags *self = GDATA_EXIF_TAGS (parsable);
 
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/photos/exif/2007";) == FALSE)
+		return GDATA_PARSABLE_CLASS (gdata_exif_tags_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+
 	if (xmlStrcmp (node->name, (xmlChar*) "distance") == 0 ) {
 		/* exif:distance */
 		xmlChar *distance = xmlNodeListGetString (doc, node->children, TRUE);
diff --git a/gdata/gd/gdata-gd-name.c b/gdata/gd/gdata-gd-name.c
index 9079f35..bccdd8a 100644
--- a/gdata/gd/gdata-gd-name.c
+++ b/gdata/gd/gdata-gd-name.c
@@ -287,19 +287,22 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataGDNamePrivate *priv = GDATA_GD_NAME (parsable)->priv;
 
-	PARSE_STRING_ELEMENT ("givenName", given_name)
-	else PARSE_STRING_ELEMENT ("additionalName", additional_name)
-	else PARSE_STRING_ELEMENT ("familyName", family_name)
-	else PARSE_STRING_ELEMENT ("namePrefix", prefix)
-	else PARSE_STRING_ELEMENT ("nameSuffix", suffix)
-	else if (xmlStrcmp (node->name, (xmlChar*) "fullName") == 0) {
-		/* gd:fullName */
-		if (priv->full_name != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-		priv->full_name = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (GDATA_PARSABLE_CLASS (gdata_gd_name_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == TRUE) {
+		PARSE_STRING_ELEMENT ("givenName", given_name)
+		else PARSE_STRING_ELEMENT ("additionalName", additional_name)
+		else PARSE_STRING_ELEMENT ("familyName", family_name)
+		else PARSE_STRING_ELEMENT ("namePrefix", prefix)
+		else PARSE_STRING_ELEMENT ("nameSuffix", suffix)
+		else if (xmlStrcmp (node->name, (xmlChar*) "fullName") == 0) {
+			/* gd:fullName */
+			if (priv->full_name != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+			priv->full_name = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_gd_name_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_gd_name_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/gd/gdata-gd-organization.c b/gdata/gd/gdata-gd-organization.c
index 12ea137..dcbbaa1 100644
--- a/gdata/gd/gdata-gd-organization.c
+++ b/gdata/gd/gdata-gd-organization.c
@@ -396,6 +396,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataGDOrganizationPrivate *priv = GDATA_GD_ORGANIZATION (parsable)->priv;
 
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == FALSE)
+		return GDATA_PARSABLE_CLASS (gdata_gd_organization_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+
 	if (xmlStrcmp (node->name, (xmlChar*) "orgName") == 0) {
 		/* gd:orgName */
 		if (priv->name != NULL)
@@ -433,9 +436,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		}
 
 		priv->location = location;
-	} else if (GDATA_PARSABLE_CLASS (gdata_gd_organization_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_gd_organization_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/gd/gdata-gd-postal-address.c b/gdata/gd/gdata-gd-postal-address.c
index 1d579f2..56ac8fb 100644
--- a/gdata/gd/gdata-gd-postal-address.c
+++ b/gdata/gd/gdata-gd-postal-address.c
@@ -589,20 +589,21 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataGDPostalAddressPrivate *priv = GDATA_GD_POSTAL_ADDRESS (parsable)->priv;
 
-	PARSE_STRING_ELEMENT ("agent", agent)
-	else PARSE_STRING_ELEMENT ("housename", house_name)
-	else PARSE_STRING_ELEMENT ("pobox", po_box)
-	else PARSE_STRING_ELEMENT ("street", street)
-	else PARSE_STRING_ELEMENT ("neighborhood", neighborhood)
-	else PARSE_STRING_ELEMENT ("city", city)
-	else PARSE_STRING_ELEMENT ("subregion", subregion)
-	else PARSE_STRING_ELEMENT ("region", region)
-	else PARSE_STRING_ELEMENT ("postcode", postcode)
-	else PARSE_STRING_ELEMENT ("country", country)
-	else PARSE_STRING_ELEMENT ("formattedAddress", formatted_address)
-	else if (GDATA_PARSABLE_CLASS (gdata_gd_postal_address_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == TRUE) {
+		PARSE_STRING_ELEMENT ("agent", agent)
+		else PARSE_STRING_ELEMENT ("housename", house_name)
+		else PARSE_STRING_ELEMENT ("pobox", po_box)
+		else PARSE_STRING_ELEMENT ("street", street)
+		else PARSE_STRING_ELEMENT ("neighborhood", neighborhood)
+		else PARSE_STRING_ELEMENT ("city", city)
+		else PARSE_STRING_ELEMENT ("subregion", subregion)
+		else PARSE_STRING_ELEMENT ("region", region)
+		else PARSE_STRING_ELEMENT ("postcode", postcode)
+		else PARSE_STRING_ELEMENT ("country", country)
+		else PARSE_STRING_ELEMENT ("formattedAddress", formatted_address)
+		else return GDATA_PARSABLE_CLASS (gdata_gd_postal_address_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_gd_postal_address_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/gd/gdata-gd-when.c b/gdata/gd/gdata-gd-when.c
index 5a7046f..437a515 100644
--- a/gdata/gd/gdata-gd-when.c
+++ b/gdata/gd/gdata-gd-when.c
@@ -293,16 +293,16 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataGDWhenPrivate *priv = GDATA_GD_WHEN (parsable)->priv;
 
-	if (xmlStrcmp (node->name, (xmlChar*) "reminder") == 0) {
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "reminder") == 0) {
 		/* gd:reminder */
 		GDataGDReminder *reminder = GDATA_GD_REMINDER (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_REMINDER, doc, node, NULL, error));
 		if (reminder == NULL)
 			return FALSE;
 
 		priv->reminders = g_list_prepend (priv->reminders, reminder);
-	} else if (GDATA_PARSABLE_CLASS (gdata_gd_when_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_gd_when_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/gdata-access-rule.c b/gdata/gdata-access-rule.c
index 618b30a..29f6ce3 100644
--- a/gdata/gdata-access-rule.c
+++ b/gdata/gdata-access-rule.c
@@ -206,40 +206,37 @@ gdata_access_rule_finalize (GObject *object)
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
-	GDataAccessRule *self;
-
-	g_return_val_if_fail (GDATA_IS_ACCESS_RULE (parsable), FALSE);
-	g_return_val_if_fail (doc != NULL, FALSE);
-	g_return_val_if_fail (node != NULL, FALSE);
-
-	self = GDATA_ACCESS_RULE (parsable);
-
-	if (xmlStrcmp (node->name, (xmlChar*) "role") == 0) {
-		/* gAcl:role */
-		xmlChar *role = xmlGetProp (node, (xmlChar*) "value");
-		if (role == NULL)
-			return gdata_parser_error_required_property_missing (node, "value", error);
-		self->priv->role = (gchar*) role;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "scope") == 0) {
-		/* gAcl:scope */
-		xmlChar *scope_type, *scope_value;
-
-		scope_type = xmlGetProp (node, (xmlChar*) "type");
-		if (scope_type == NULL)
-			return gdata_parser_error_required_property_missing (node, "type", error);
-
-		scope_value = xmlGetProp (node, (xmlChar*) "value");
-
-		if (xmlStrcmp (scope_type, (xmlChar*) "default") == 0 && scope_value == NULL) {
-			xmlFree (scope_type);
-			return gdata_parser_error_required_property_missing (node, "value", error);
+	GDataAccessRule *self = GDATA_ACCESS_RULE (parsable);
+
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/acl/2007";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "role") == 0) {
+			/* gAcl:role */
+			xmlChar *role = xmlGetProp (node, (xmlChar*) "value");
+			if (role == NULL)
+				return gdata_parser_error_required_property_missing (node, "value", error);
+			self->priv->role = (gchar*) role;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "scope") == 0) {
+			/* gAcl:scope */
+			xmlChar *scope_type, *scope_value;
+
+			scope_type = xmlGetProp (node, (xmlChar*) "type");
+			if (scope_type == NULL)
+				return gdata_parser_error_required_property_missing (node, "type", error);
+
+			scope_value = xmlGetProp (node, (xmlChar*) "value");
+
+			if (xmlStrcmp (scope_type, (xmlChar*) "default") == 0 && scope_value == NULL) {
+				xmlFree (scope_type);
+				return gdata_parser_error_required_property_missing (node, "value", error);
+			}
+
+			self->priv->scope_type = (gchar*) scope_type;
+			self->priv->scope_value = (gchar*) scope_value;
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_access_rule_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-
-		self->priv->scope_type = (gchar*) scope_type;
-		self->priv->scope_value = (gchar*) scope_value;
-	} else if (GDATA_PARSABLE_CLASS (gdata_access_rule_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_access_rule_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/gdata-entry.c b/gdata/gdata-entry.c
index 4f0e4f1..82d1af1 100644
--- a/gdata/gdata-entry.c
+++ b/gdata/gdata-entry.c
@@ -372,84 +372,81 @@ pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointe
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
-	GDataEntry *self;
-
-	g_return_val_if_fail (GDATA_IS_ENTRY (parsable), FALSE);
-	g_return_val_if_fail (doc != NULL, FALSE);
-	g_return_val_if_fail (node != NULL, FALSE);
-
-	self = GDATA_ENTRY (parsable);
-
-	if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
-		/* atom:title */
-		xmlChar *title = xmlNodeListGetString (doc, node->children, TRUE);
-
-		/* Title can be empty */
-		self->priv->title = (title != NULL) ? (gchar*) title : g_strdup ("");
-	} else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0) {
-		/* atom:id */
-		g_free (self->priv->id);
-		self->priv->id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "updated") == 0) {
-		/* atom:updated */
-		xmlChar *updated;
-
-		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 (node, (gchar*) updated, error);
+	GDataEntry *self = GDATA_ENTRY (parsable);
+
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2005/Atom";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
+			/* atom:title */
+			xmlChar *title = xmlNodeListGetString (doc, node->children, TRUE);
+
+			/* Title can be empty */
+			self->priv->title = (title != NULL) ? (gchar*) title : g_strdup ("");
+		} else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0) {
+			/* atom:id */
+			g_free (self->priv->id);
+			self->priv->id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "updated") == 0) {
+			/* atom:updated */
+			xmlChar *updated;
+
+			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 (node, (gchar*) updated, error);
+				xmlFree (updated);
+				return FALSE;
+			}
 			xmlFree (updated);
-			return FALSE;
-		}
-		xmlFree (updated);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "published") == 0) {
-		/* atom:published */
-		xmlChar *published;
-
-		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 (node, (gchar*) published, error);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "published") == 0) {
+			/* atom:published */
+			xmlChar *published;
+
+			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 (node, (gchar*) published, error);
+				xmlFree (published);
+				return FALSE;
+			}
 			xmlFree (published);
-			return FALSE;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "category") == 0) {
+			/* atom:category */
+			GDataCategory *category = GDATA_CATEGORY (_gdata_parsable_new_from_xml_node (GDATA_TYPE_CATEGORY, doc, node, NULL, error));
+			if (category == NULL)
+				return FALSE;
+
+			self->priv->categories = g_list_prepend (self->priv->categories, category);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
+			/* atom:content */
+			xmlChar *content = xmlNodeListGetString (doc, node->children, TRUE);
+			if (content == NULL)
+				content = xmlGetProp (node, (xmlChar*) "src");
+			self->priv->content = (gchar*) content;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "link") == 0) {
+			/* atom:link */
+			GDataLink *link = GDATA_LINK (_gdata_parsable_new_from_xml_node (GDATA_TYPE_LINK, doc, node, NULL, error));
+			if (link == NULL)
+				return FALSE;
+
+			self->priv->links = g_list_prepend (self->priv->links, link);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "author") == 0) {
+			/* atom:author */
+			GDataAuthor *author = GDATA_AUTHOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_AUTHOR, doc, node, NULL, error));
+			if (author == NULL)
+				return FALSE;
+
+			self->priv->authors = g_list_prepend (self->priv->authors, author);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "summary") == 0) {
+			/* atom:summary */
+			self->priv->summary = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "rights") == 0) {
+			/* atom:rights */
+			self->priv->rights = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_entry_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-		xmlFree (published);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "category") == 0) {
-		/* atom:category */
-		GDataCategory *category = GDATA_CATEGORY (_gdata_parsable_new_from_xml_node (GDATA_TYPE_CATEGORY, doc, node, NULL, error));
-		if (category == NULL)
-			return FALSE;
-
-		self->priv->categories = g_list_prepend (self->priv->categories, category);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
-		/* atom:content */
-		xmlChar *content = xmlNodeListGetString (doc, node->children, TRUE);
-		if (content == NULL)
-			content = xmlGetProp (node, (xmlChar*) "src");
-		self->priv->content = (gchar*) content;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "link") == 0) {
-		/* atom:link */
-		GDataLink *link = GDATA_LINK (_gdata_parsable_new_from_xml_node (GDATA_TYPE_LINK, doc, node, NULL, error));
-		if (link == NULL)
-			return FALSE;
-
-		self->priv->links = g_list_prepend (self->priv->links, link);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "author") == 0) {
-		/* atom:author */
-		GDataAuthor *author = GDATA_AUTHOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_AUTHOR, doc, node, NULL, error));
-		if (author == NULL)
-			return FALSE;
-
-		self->priv->authors = g_list_prepend (self->priv->authors, author);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "summary") == 0) {
-		/* atom:summary */
-		self->priv->summary = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "rights") == 0) {
-		/* atom:rights */
-		self->priv->rights = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (GDATA_PARSABLE_CLASS (gdata_entry_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_entry_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/gdata-feed.c b/gdata/gdata-feed.c
index 2cbae6f..2dc93b4 100644
--- a/gdata/gdata-feed.c
+++ b/gdata/gdata-feed.c
@@ -398,160 +398,161 @@ typedef struct {
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
-	GDataFeed *self;
+	GDataFeed *self = GDATA_FEED (parsable);
 	ParseData *data = user_data;
 
-	g_return_val_if_fail (GDATA_IS_FEED (parsable), FALSE);
-	g_return_val_if_fail (doc != NULL, FALSE);
-	g_return_val_if_fail (node != NULL, FALSE);
-
-	self = GDATA_FEED (parsable);
-
-	if (xmlStrcmp (node->name, (xmlChar*) "entry") == 0) {
-		/* atom:entry */
-		GDataEntry *entry;
-		GType entry_type;
-
-		/* Allow @data to be %NULL, and assume we're parsing a vanilla feed, so that we can test #GDataFeed in tests/general.c. A little hacky,
-		 * but not too much so, and valuable for testing. */
-		entry_type = (data != NULL) ? data->entry_type : GDATA_TYPE_ENTRY;
-		entry = GDATA_ENTRY (_gdata_parsable_new_from_xml_node (entry_type, doc, node, NULL, error));
-		if (entry == NULL)
-			return FALSE;
-
-		/* Calls the callbacks in the main thread */
-		if (data != NULL)
-			_gdata_feed_call_progress_callback (self, data, entry);
-		_gdata_feed_add_entry (self, entry);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
-		/* atom:title */
-		if (self->priv->title != NULL)
-			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 (node, error);
-
-		self->priv->subtitle = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0 && xmlStrcmp (node->ns->href, (xmlChar*) "http://www.w3.org/2005/Atom";) == 0) {
-		/* atom:id */
-		/* The namespace check is necessary because there's an "id" element in the gphoto namespace (PicasaWeb service) */
-		if (self->priv->id != NULL)
-			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) {
-		/* atom:updated */
-		xmlChar *updated_string;
-
-		/* Duplicate checking */
-		if (self->priv->updated.tv_sec != 0 || self->priv->updated.tv_usec != 0)
-			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 (node, (gchar*) updated_string, error);
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2005/Atom";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "entry") == 0) {
+			/* atom:entry */
+			GDataEntry *entry;
+			GType entry_type;
+
+			/* Allow @data to be %NULL, and assume we're parsing a vanilla feed, so that we can test #GDataFeed in tests/general.c. A little hacky,
+			 * but not too much so, and valuable for testing. */
+			entry_type = (data != NULL) ? data->entry_type : GDATA_TYPE_ENTRY;
+			entry = GDATA_ENTRY (_gdata_parsable_new_from_xml_node (entry_type, doc, node, NULL, error));
+			if (entry == NULL)
+				return FALSE;
+
+			/* Calls the callbacks in the main thread */
+			if (data != NULL)
+				_gdata_feed_call_progress_callback (self, data, entry);
+			_gdata_feed_add_entry (self, entry);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
+			/* atom:title */
+			if (self->priv->title != NULL)
+				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 (node, error);
+
+			self->priv->subtitle = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0 && xmlStrcmp (node->ns->href, (xmlChar*) "http://www.w3.org/2005/Atom";) == 0) {
+			/* atom:id */
+			/* The namespace check is necessary because there's an "id" element in the gphoto namespace (PicasaWeb service) */
+			if (self->priv->id != NULL)
+				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) {
+			/* atom:updated */
+			xmlChar *updated_string;
+
+			/* Duplicate checking */
+			if (self->priv->updated.tv_sec != 0 || self->priv->updated.tv_usec != 0)
+				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 (node, (gchar*) updated_string, error);
+				xmlFree (updated_string);
+				return FALSE;
+			}
 			xmlFree (updated_string);
-			return FALSE;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "category") == 0) {
+			/* atom:category */
+			GDataCategory *category = GDATA_CATEGORY (_gdata_parsable_new_from_xml_node (GDATA_TYPE_CATEGORY, doc, node, NULL, error));
+			if (category == NULL)
+				return FALSE;
+
+			self->priv->categories = g_list_prepend (self->priv->categories, category);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "logo") == 0) {
+			/* atom:logo */
+			if (self->priv->logo != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+
+			self->priv->logo = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "icon") == 0) {
+			/* atom:icon */
+			if (self->priv->icon != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+
+			self->priv->icon = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "link") == 0) {
+			/* atom:link */
+			GDataLink *link = GDATA_LINK (_gdata_parsable_new_from_xml_node (GDATA_TYPE_LINK, doc, node, NULL, error));
+			if (link == NULL)
+				return FALSE;
+
+			self->priv->links = g_list_prepend (self->priv->links, link);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "author") == 0) {
+			/* atom:author */
+			GDataAuthor *author = GDATA_AUTHOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_AUTHOR, doc, node, NULL, error));
+			if (author == NULL)
+				return FALSE;
+
+			self->priv->authors = g_list_prepend (self->priv->authors, author);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "generator") == 0) {
+			/* atom:generator */
+			GDataGenerator *generator;
+
+			/* Duplicate checking */
+			if (self->priv->generator != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+
+			generator = GDATA_GENERATOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GENERATOR, doc, node, NULL, error));
+			if (generator == NULL)
+				return FALSE;
+
+			self->priv->generator = generator;
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else if (gdata_parser_is_namespace (node, "http://a9.com/-/spec/opensearch/1.1/";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "totalResults") == 0) {
+			/* openSearch:totalResults */
+			xmlChar *total_results_string;
+
+			/* Duplicate checking */
+			if (self->priv->total_results != 0)
+				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 (node, error);
+
+			self->priv->total_results = strtoul ((gchar*) total_results_string, NULL, 10);
+			xmlFree (total_results_string);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "startIndex") == 0) {
+			/* openSearch:startIndex */
+			xmlChar *start_index_string;
+
+			/* Duplicate checking */
+			if (self->priv->start_index != 0)
+				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 (node, error);
+
+			self->priv->start_index = strtoul ((gchar*) start_index_string, NULL, 10);
+			xmlFree (start_index_string);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "itemsPerPage") == 0) {
+			/* openSearch:itemsPerPage */
+			xmlChar *items_per_page_string;
+
+			/* Duplicate checking */
+			if (self->priv->items_per_page != 0)
+				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 (node, error);
+
+			self->priv->items_per_page = strtoul ((gchar*) items_per_page_string, NULL, 10);
+			xmlFree (items_per_page_string);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-		xmlFree (updated_string);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "category") == 0) {
-		/* atom:category */
-		GDataCategory *category = GDATA_CATEGORY (_gdata_parsable_new_from_xml_node (GDATA_TYPE_CATEGORY, doc, node, NULL, error));
-		if (category == NULL)
-			return FALSE;
-
-		self->priv->categories = g_list_prepend (self->priv->categories, category);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "logo") == 0) {
-		/* atom:logo */
-		if (self->priv->logo != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-
-		self->priv->logo = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "icon") == 0) {
-		/* atom:icon */
-		if (self->priv->icon != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-
-		self->priv->icon = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "link") == 0) {
-		/* atom:link */
-		GDataLink *link = GDATA_LINK (_gdata_parsable_new_from_xml_node (GDATA_TYPE_LINK, doc, node, NULL, error));
-		if (link == NULL)
-			return FALSE;
-
-		self->priv->links = g_list_prepend (self->priv->links, link);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "author") == 0) {
-		/* atom:author */
-		GDataAuthor *author = GDATA_AUTHOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_AUTHOR, doc, node, NULL, error));
-		if (author == NULL)
-			return FALSE;
-
-		self->priv->authors = g_list_prepend (self->priv->authors, author);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "generator") == 0) {
-		/* atom:generator */
-		GDataGenerator *generator;
-
-		/* Duplicate checking */
-		if (self->priv->generator != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-
-		generator = GDATA_GENERATOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GENERATOR, doc, node, NULL, error));
-		if (generator == NULL)
-			return FALSE;
-
-		self->priv->generator = generator;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "totalResults") == 0) {
-		/* openSearch:totalResults */
-		xmlChar *total_results_string;
-
-		/* Duplicate checking */
-		if (self->priv->total_results != 0)
-			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 (node, error);
-
-		self->priv->total_results = strtoul ((gchar*) total_results_string, NULL, 10);
-		xmlFree (total_results_string);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "startIndex") == 0) {
-		/* openSearch:startIndex */
-		xmlChar *start_index_string;
-
-		/* Duplicate checking */
-		if (self->priv->start_index != 0)
-			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 (node, error);
-
-		self->priv->start_index = strtoul ((gchar*) start_index_string, NULL, 10);
-		xmlFree (start_index_string);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "itemsPerPage") == 0) {
-		/* openSearch:itemsPerPage */
-		xmlChar *items_per_page_string;
-
-		/* Duplicate checking */
-		if (self->priv->items_per_page != 0)
-			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 (node, error);
-
-		self->priv->items_per_page = strtoul ((gchar*) items_per_page_string, NULL, 10);
-		xmlFree (items_per_page_string);
-	} else if (GDATA_PARSABLE_CLASS (gdata_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/gdata-parser.c b/gdata/gdata-parser.c
index 7f13761..88ed1c8 100644
--- a/gdata/gdata-parser.c
+++ b/gdata/gdata-parser.c
@@ -204,6 +204,27 @@ gdata_parser_date_from_time_val (GTimeVal *_time)
 	return g_strdup_printf ("%4d-%02d-%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
 }
 
+/*
+ * gdata_parser_is_namespace:
+ * @element: the element to check
+ * @namespace_uri: the URI of the desired namespace
+ *
+ * Checks whether @element is in the namespace identified by @namespace_uri. If @element isn't in a namespace,
+ * %FALSE is returned.
+ *
+ * Return value: %TRUE if @element is in @namespace_uri; %FALSE otherwise
+ *
+ * Since: 0.6.4
+ */
+gboolean
+gdata_parser_is_namespace (xmlNode *element, const gchar *namespace_uri)
+{
+	if ((element->ns != NULL && xmlStrcmp (element->ns->href, (const xmlChar*) namespace_uri) == 0) ||
+	    (element->ns == NULL && strcmp (namespace_uri, "http://www.w3.org/2005/Atom";) == 0))
+		return TRUE;
+	return FALSE;
+}
+
 void
 gdata_parser_string_append_escaped (GString *xml_string, const gchar *pre, const gchar *element_content, const gchar *post)
 {
diff --git a/gdata/gdata-parser.h b/gdata/gdata-parser.h
index 1d3474e..3fa4e77 100644
--- a/gdata/gdata-parser.h
+++ b/gdata/gdata-parser.h
@@ -33,6 +33,9 @@ gboolean gdata_parser_error_required_element_missing (const gchar *element_name,
 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;
+
+gboolean gdata_parser_is_namespace (xmlNode *element, const gchar *namespace_uri);
+
 void gdata_parser_string_append_escaped (GString *xml_string, const gchar *pre, const gchar *element_content, const gchar *post);
 gchar *gdata_parser_utf8_trim_whitespace (const gchar *s) G_GNUC_WARN_UNUSED_RESULT;
 
diff --git a/gdata/georss/gdata-georss-where.c b/gdata/georss/gdata-georss-where.c
index fcc1b12..b6ed56e 100644
--- a/gdata/georss/gdata-georss-where.c
+++ b/gdata/georss/gdata-georss-where.c
@@ -85,7 +85,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataGeoRSSWhere *self = GDATA_GEORSS_WHERE (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "Point") == 0) {
+	if (gdata_parser_is_namespace (node, "http://www.opengis.net/gml";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "Point") == 0) {
 		/* gml:Point */
 		gboolean found_pos = FALSE;
 		xmlNode *child;
@@ -115,12 +116,10 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		if (found_pos == FALSE)
 			return gdata_parser_error_required_element_missing ("pos", "gml:Point", error);
-	} else if (GDATA_PARSABLE_CLASS (gdata_georss_where_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+		return TRUE;
 	}
 
-	return TRUE;
+	return GDATA_PARSABLE_CLASS (gdata_georss_where_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 }
 
 static void
diff --git a/gdata/media/gdata-media-group.c b/gdata/media/gdata-media-group.c
index e0753ea..2778584 100644
--- a/gdata/media/gdata-media-group.c
+++ b/gdata/media/gdata-media-group.c
@@ -140,110 +140,113 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataMediaGroup *self = GDATA_MEDIA_GROUP (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
-		/* media:title */
-		self->priv->title = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "description") == 0) {
-		/* media:description */
-		self->priv->description = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "keywords") == 0) {
-		/* media:keywords */
-		self->priv->keywords = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "category") == 0) {
-		/* media:category */
-		GDataMediaCategory *category = GDATA_MEDIA_CATEGORY (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_CATEGORY, doc,
-													node, NULL, error));
-		if (category == NULL)
-			return FALSE;
-
-		gdata_media_group_set_category (self, category);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
-		/* media:content */
-		GDataMediaContent *content = GDATA_MEDIA_CONTENT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_CONTENT, doc, node, NULL, error));
-		if (content == NULL)
-			return FALSE;
-
-		_gdata_media_group_add_content (self, content);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "credit") == 0) {
-		/* media:credit */
-		GDataMediaCredit *credit = GDATA_MEDIA_CREDIT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_CREDIT, doc, node, NULL, error));
-		if (credit == NULL)
-			return FALSE;
-
-		if (self->priv->credit != NULL) {
-			g_object_unref (credit);
-			return gdata_parser_error_duplicate_element (node, error);
-		}
-
-		_gdata_media_group_set_credit (self, credit);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "player") == 0) {
-		/* media:player */
-		xmlChar *player_uri = xmlGetProp (node, (xmlChar*) "url");
-
-		g_free (self->priv->player_uri);
-		self->priv->player_uri = (gchar*) player_uri;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "rating") == 0) {
-		/* media:rating */
-		xmlChar *countries;
-		gchar **country_list, **country;
-
-		countries = xmlGetProp (node, (xmlChar*) "country");
-		country_list = g_strsplit ((const gchar*) countries, ",", -1);
-		xmlFree (countries);
-
-		/* Add all the listed countries to the restricted countries table */
-		for (country = country_list; *country != NULL; country++)
-			g_hash_table_insert (self->priv->restricted_countries, *country, GUINT_TO_POINTER (TRUE));
-		g_free (country_list);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "restriction") == 0) {
-		/* media:restriction */
-		xmlChar *type, *countries, *relationship;
-		gchar **country_list, **country;
-		gboolean relationship_bool;
-
-		/* Check the type property is "country" */
-		type = xmlGetProp (node, (xmlChar*) "type");
-		if (xmlStrcmp (type, (xmlChar*) "country") != 0) {
-			gdata_parser_error_unknown_property_value (node, "type", (gchar*) type, error);
+	if (gdata_parser_is_namespace (node, "http://search.yahoo.com/mrss/";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
+			/* media:title */
+			self->priv->title = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "description") == 0) {
+			/* media:description */
+			self->priv->description = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "keywords") == 0) {
+			/* media:keywords */
+			self->priv->keywords = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "category") == 0) {
+			/* media:category */
+			GDataMediaCategory *category = GDATA_MEDIA_CATEGORY (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_CATEGORY, doc,
+														node, NULL, error));
+			if (category == NULL)
+				return FALSE;
+
+			gdata_media_group_set_category (self, category);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
+			/* media:content */
+			GDataMediaContent *content = GDATA_MEDIA_CONTENT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_CONTENT, doc, node, NULL, error));
+			if (content == NULL)
+				return FALSE;
+
+			_gdata_media_group_add_content (self, content);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "credit") == 0) {
+			/* media:credit */
+			GDataMediaCredit *credit = GDATA_MEDIA_CREDIT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_CREDIT, doc, node, NULL, error));
+			if (credit == NULL)
+				return FALSE;
+
+			if (self->priv->credit != NULL) {
+				g_object_unref (credit);
+				return gdata_parser_error_duplicate_element (node, error);
+			}
+
+			_gdata_media_group_set_credit (self, credit);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "player") == 0) {
+			/* media:player */
+			xmlChar *player_uri = xmlGetProp (node, (xmlChar*) "url");
+
+			g_free (self->priv->player_uri);
+			self->priv->player_uri = (gchar*) player_uri;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "rating") == 0) {
+			/* media:rating */
+			xmlChar *countries;
+			gchar **country_list, **country;
+
+			countries = xmlGetProp (node, (xmlChar*) "country");
+			country_list = g_strsplit ((const gchar*) countries, ",", -1);
+			xmlFree (countries);
+
+			/* Add all the listed countries to the restricted countries table */
+			for (country = country_list; *country != NULL; country++)
+				g_hash_table_insert (self->priv->restricted_countries, *country, GUINT_TO_POINTER (TRUE));
+			g_free (country_list);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "restriction") == 0) {
+			/* media:restriction */
+			xmlChar *type, *countries, *relationship;
+			gchar **country_list, **country;
+			gboolean relationship_bool;
+
+			/* Check the type property is "country" */
+			type = xmlGetProp (node, (xmlChar*) "type");
+			if (xmlStrcmp (type, (xmlChar*) "country") != 0) {
+				gdata_parser_error_unknown_property_value (node, "type", (gchar*) type, error);
+				xmlFree (type);
+				return FALSE;
+			}
 			xmlFree (type);
-			return FALSE;
-		}
-		xmlFree (type);
-
-		relationship = xmlGetProp (node, (xmlChar*) "relationship");
-		if (xmlStrcmp (relationship, (xmlChar*) "allow") == 0)
-			relationship_bool = FALSE; /* it's *not* a restricted country */
-		else if (xmlStrcmp (relationship, (xmlChar*) "deny") == 0)
-			relationship_bool = TRUE; /* it *is* a restricted country */
-		else {
-			gdata_parser_error_unknown_property_value (node, "relationship", (gchar*) relationship, error);
+
+			relationship = xmlGetProp (node, (xmlChar*) "relationship");
+			if (xmlStrcmp (relationship, (xmlChar*) "allow") == 0)
+				relationship_bool = FALSE; /* it's *not* a restricted country */
+			else if (xmlStrcmp (relationship, (xmlChar*) "deny") == 0)
+				relationship_bool = TRUE; /* it *is* a restricted country */
+			else {
+				gdata_parser_error_unknown_property_value (node, "relationship", (gchar*) relationship, error);
+				xmlFree (relationship);
+				return FALSE;
+			}
 			xmlFree (relationship);
-			return FALSE;
+
+			countries = xmlNodeListGetString (doc, node->children, TRUE);
+			country_list = g_strsplit ((const gchar*) countries, " ", -1);
+			xmlFree (countries);
+
+			/* Add "all" to the table, since it's an exception table */
+			g_hash_table_insert (self->priv->restricted_countries, g_strdup ("all"), GUINT_TO_POINTER (!relationship_bool));
+
+			/* Add all the listed countries to the restricted countries table */
+			for (country = country_list; *country != NULL; country++)
+				g_hash_table_insert (self->priv->restricted_countries, *country, GUINT_TO_POINTER (relationship_bool));
+			g_free (country_list);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "thumbnail") == 0) {
+			/* media:thumbnail */
+			GDataMediaThumbnail *thumb = GDATA_MEDIA_THUMBNAIL (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_THUMBNAIL, doc,
+													       node, NULL, error));
+			if (thumb == NULL)
+				return FALSE;
+
+			self->priv->thumbnails = g_list_prepend (self->priv->thumbnails, thumb);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_media_group_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-		xmlFree (relationship);
-
-		countries = xmlNodeListGetString (doc, node->children, TRUE);
-		country_list = g_strsplit ((const gchar*) countries, " ", -1);
-		xmlFree (countries);
-
-		/* Add "all" to the table, since it's an exception table */
-		g_hash_table_insert (self->priv->restricted_countries, g_strdup ("all"), GUINT_TO_POINTER (!relationship_bool));
-
-		/* Add all the listed countries to the restricted countries table */
-		for (country = country_list; *country != NULL; country++)
-			g_hash_table_insert (self->priv->restricted_countries, *country, GUINT_TO_POINTER (relationship_bool));
-		g_free (country_list);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "thumbnail") == 0) {
-		/* media:thumbnail */
-		GDataMediaThumbnail *thumb = GDATA_MEDIA_THUMBNAIL (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_THUMBNAIL, doc,
-												       node, NULL, error));
-		if (thumb == NULL)
-			return FALSE;
-
-		self->priv->thumbnails = g_list_prepend (self->priv->thumbnails, thumb);
-	} else if (GDATA_PARSABLE_CLASS (gdata_media_group_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_media_group_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/calendar/gdata-calendar-calendar.c b/gdata/services/calendar/gdata-calendar-calendar.c
index 9b2e72d..3237aab 100644
--- a/gdata/services/calendar/gdata-calendar-calendar.c
+++ b/gdata/services/calendar/gdata-calendar-calendar.c
@@ -282,71 +282,70 @@ gdata_calendar_calendar_new (const gchar *id)
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
-	GDataCalendarCalendar *self;
-
-	g_return_val_if_fail (GDATA_IS_CALENDAR_CALENDAR (parsable), FALSE);
-	g_return_val_if_fail (doc != NULL, FALSE);
-	g_return_val_if_fail (node != NULL, FALSE);
-
-	self = GDATA_CALENDAR_CALENDAR (parsable);
-
-	if (xmlStrcmp (node->name, (xmlChar*) "timezone") == 0) {
-		/* gCal:timezone */
-		xmlChar *_timezone = xmlGetProp (node, (xmlChar*) "value");
-		if (_timezone == NULL)
-			return gdata_parser_error_required_property_missing (node, "value", error);
-		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 (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 (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) {
-		/* gCal:color */
-		xmlChar *value;
-		GDataColor colour;
-
-		value = xmlGetProp (node, (xmlChar*) "value");
-		if (value == NULL)
-			return gdata_parser_error_required_property_missing (node, "value", error);
-		if (gdata_color_from_hexadecimal ((gchar*) value, &colour) == FALSE) {
-			/* Error */
-			g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
-				     /* 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);
+	GDataCalendarCalendar *self = GDATA_CALENDAR_CALENDAR (parsable);
+
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/gCal/2005";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "timezone") == 0) {
+			/* gCal:timezone */
+			xmlChar *_timezone = xmlGetProp (node, (xmlChar*) "value");
+			if (_timezone == NULL)
+				return gdata_parser_error_required_property_missing (node, "value", error);
+			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 (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 (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) {
+			/* gCal:color */
+			xmlChar *value;
+			GDataColor colour;
+
+			value = xmlGetProp (node, (xmlChar*) "value");
+			if (value == NULL)
+				return gdata_parser_error_required_property_missing (node, "value", error);
+			if (gdata_color_from_hexadecimal ((gchar*) value, &colour) == FALSE) {
+				/* Error */
+				g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+					     /* 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;
+			}
+
+			gdata_calendar_calendar_set_color (self, &colour);
 			xmlFree (value);
-
-			return FALSE;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "selected") == 0) {
+			/* gCal:selected */
+			xmlChar *selected = xmlGetProp (node, (xmlChar*) "value");
+			if (selected == NULL)
+				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 (node, "value", error);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-
-		gdata_calendar_calendar_set_color (self, &colour);
-		xmlFree (value);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "selected") == 0) {
-		/* gCal:selected */
-		xmlChar *selected = xmlGetProp (node, (xmlChar*) "value");
-		if (selected == NULL)
-			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 (node, "value", error);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	           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) {
@@ -356,9 +355,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			return FALSE;
 		}
 		xmlFree (edited);
-	} else if (GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/calendar/gdata-calendar-event.c b/gdata/services/calendar/gdata-calendar-event.c
index c1834a5..2e1fd12 100644
--- a/gdata/services/calendar/gdata-calendar-event.c
+++ b/gdata/services/calendar/gdata-calendar-event.c
@@ -447,15 +447,10 @@ gdata_calendar_event_new (const gchar *id)
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
-	GDataCalendarEvent *self;
+	GDataCalendarEvent *self = GDATA_CALENDAR_EVENT (parsable);
 
-	g_return_val_if_fail (GDATA_IS_CALENDAR_EVENT (parsable), FALSE);
-	g_return_val_if_fail (doc != NULL, FALSE);
-	g_return_val_if_fail (node != NULL, FALSE);
-
-	self = GDATA_CALENDAR_EVENT (parsable);
-
-	if (xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	    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) {
@@ -465,128 +460,135 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			return FALSE;
 		}
 		xmlFree (edited);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "comments") == 0) {
-		/* gd:comments */
-		xmlChar *rel, *href, *count_hint;
-		xmlNode *child_node;
-		guint count_hint_uint;
-		/*GDataGDFeedLink *feed_link;*/
-
-		/* This is actually the child of the <comments> element */
-		child_node = node->children;
-
-		count_hint = xmlGetProp (child_node, (xmlChar*) "countHint");
-		if (count_hint == NULL)
-			count_hint_uint = 0;
-		else
-			count_hint_uint = strtoul ((gchar*) count_hint, NULL, 10);
-		xmlFree (count_hint);
-
-		rel = xmlGetProp (child_node, (xmlChar*) "rel");
-		href = xmlGetProp (child_node, (xmlChar*) "href");
-
-		/* TODO */
-		/*feed_link = gdata_gd_feed_link_new ((gchar*) href, (gchar*) rel, count_hint_uint);*/
-		/*gdata_calendar_event_set_comments_feed_link (self, feed_link);*/
-
-		xmlFree (rel);
-		xmlFree (href);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "eventStatus") == 0) {
-		/* gd:eventStatus */
-		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
-		if (value == NULL)
-			return gdata_parser_error_required_property_missing (node, "value", error);
-		self->priv->status = (gchar*) 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 (node, "value", error);
-		self->priv->visibility = (gchar*) 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 (node, "value", error);
-		self->priv->transparency = (gchar*) 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 (node, "value", error);
-		self->priv->uid = (gchar*) value;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "sequence") == 0) {
-		/* gCal:sequence */
-		xmlChar *value;
-		guint value_uint;
-
-		value = xmlGetProp (node, (xmlChar*) "value");
-		if (value == NULL)
-			return gdata_parser_error_required_property_missing (node, "value", error);
-		else
-			value_uint = strtoul ((gchar*) value, NULL, 10);
-		xmlFree (value);
-
-		gdata_calendar_event_set_sequence (self, value_uint);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "when") == 0) {
-		/* gd:when */
-		GDataGDWhen *when = GDATA_GD_WHEN (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_WHEN, doc, node, NULL, error));
-		if (when == NULL)
-			return FALSE;
-
-		gdata_calendar_event_add_time (self, when);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "guestsCanModify") == 0) {
-		/* gCal:guestsCanModify */
-		xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
-		if (value == NULL)
-			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 (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 (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 (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) {
-		/* gd:who */
-		GDataGDWho *who = GDATA_GD_WHO (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_WHO, doc, node, NULL, error));
-		if (who == NULL)
-			return FALSE;
-
-		gdata_calendar_event_add_person (self, who);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
-		/* gd:where */
-		GDataGDWhere *where = GDATA_GD_WHERE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_WHERE, doc, node, NULL, error));
-		if (where == NULL)
-			return FALSE;
-
-		gdata_calendar_event_add_place (self, where);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "recurrence") == 0) {
-		/* gd:recurrence */
-		self->priv->recurrence = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "originalEvent") == 0) {
-		/* gd:originalEvent */
-		self->priv->original_event_id = (gchar*) xmlGetProp (node, (xmlChar*) "id");
-		self->priv->original_event_uri = (gchar*) xmlGetProp (node, (xmlChar*) "href");
-	} else if (GDATA_PARSABLE_CLASS (gdata_calendar_event_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "comments") == 0) {
+			/* gd:comments */
+			xmlChar *rel, *href, *count_hint;
+			xmlNode *child_node;
+			guint count_hint_uint;
+			/*GDataGDFeedLink *feed_link;*/
+
+			/* This is actually the child of the <comments> element */
+			child_node = node->children;
+
+			count_hint = xmlGetProp (child_node, (xmlChar*) "countHint");
+			if (count_hint == NULL)
+				count_hint_uint = 0;
+			else
+				count_hint_uint = strtoul ((gchar*) count_hint, NULL, 10);
+			xmlFree (count_hint);
+
+			rel = xmlGetProp (child_node, (xmlChar*) "rel");
+			href = xmlGetProp (child_node, (xmlChar*) "href");
+
+			/* TODO */
+			/*feed_link = gdata_gd_feed_link_new ((gchar*) href, (gchar*) rel, count_hint_uint);*/
+			/*gdata_calendar_event_set_comments_feed_link (self, feed_link);*/
+
+			xmlFree (rel);
+			xmlFree (href);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "eventStatus") == 0) {
+			/* gd:eventStatus */
+			xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
+			if (value == NULL)
+				return gdata_parser_error_required_property_missing (node, "value", error);
+			self->priv->status = (gchar*) 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 (node, "value", error);
+			self->priv->visibility = (gchar*) 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 (node, "value", error);
+			self->priv->transparency = (gchar*) value;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "when") == 0) {
+			/* gd:when */
+			GDataGDWhen *when = GDATA_GD_WHEN (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_WHEN, doc, node, NULL, error));
+			if (when == NULL)
+				return FALSE;
+
+			gdata_calendar_event_add_time (self, when);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "who") == 0) {
+			/* gd:who */
+			GDataGDWho *who = GDATA_GD_WHO (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_WHO, doc, node, NULL, error));
+			if (who == NULL)
+				return FALSE;
+
+			gdata_calendar_event_add_person (self, who);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
+			/* gd:where */
+			GDataGDWhere *where = GDATA_GD_WHERE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_WHERE, doc, node, NULL, error));
+			if (where == NULL)
+				return FALSE;
+
+			gdata_calendar_event_add_place (self, where);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "recurrence") == 0) {
+			/* gd:recurrence */
+			self->priv->recurrence = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "originalEvent") == 0) {
+			/* gd:originalEvent */
+			self->priv->original_event_id = (gchar*) xmlGetProp (node, (xmlChar*) "id");
+			self->priv->original_event_uri = (gchar*) xmlGetProp (node, (xmlChar*) "href");
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_calendar_event_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/gCal/2005";) == TRUE) {
+		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 (node, "value", error);
+			self->priv->uid = (gchar*) value;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "sequence") == 0) {
+			/* gCal:sequence */
+			xmlChar *value;
+			guint value_uint;
+
+			value = xmlGetProp (node, (xmlChar*) "value");
+			if (value == NULL)
+				return gdata_parser_error_required_property_missing (node, "value", error);
+			else
+				value_uint = strtoul ((gchar*) value, NULL, 10);
+			xmlFree (value);
+
+			gdata_calendar_event_set_sequence (self, value_uint);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "guestsCanModify") == 0) {
+			/* gCal:guestsCanModify */
+			xmlChar *value = xmlGetProp (node, (xmlChar*) "value");
+			if (value == NULL)
+				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 (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 (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 (node, "value", error);
+			gdata_calendar_event_set_anyone_can_add_self (self, (xmlStrcmp (value, (xmlChar*) "true") == 0) ? TRUE : FALSE);
+			xmlFree (value);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_calendar_event_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_calendar_event_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/calendar/gdata-calendar-feed.c b/gdata/services/calendar/gdata-calendar-feed.c
index 4e0fa67..8b1f4cc 100644
--- a/gdata/services/calendar/gdata-calendar-feed.c
+++ b/gdata/services/calendar/gdata-calendar-feed.c
@@ -132,6 +132,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataCalendarFeed *self = GDATA_CALENDAR_FEED (parsable);
 
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/gCal/2005";) == FALSE)
+		return GDATA_PARSABLE_CLASS (gdata_calendar_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+
 	if (xmlStrcmp (node->name, (xmlChar*) "timezone") == 0) {
 		/* gCal:timezone */
 		xmlChar *_timezone = xmlGetProp (node, (xmlChar*) "value");
@@ -146,9 +149,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			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) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_calendar_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/contacts/gdata-contacts-contact.c b/gdata/services/contacts/gdata-contacts-contact.c
index af15066..4e35fe3 100644
--- a/gdata/services/contacts/gdata-contacts-contact.c
+++ b/gdata/services/contacts/gdata-contacts-contact.c
@@ -290,15 +290,10 @@ gdata_contacts_contact_new (const gchar *id)
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
-	GDataContactsContact *self;
+	GDataContactsContact *self = GDATA_CONTACTS_CONTACT (parsable);
 
-	g_return_val_if_fail (GDATA_IS_CONTACTS_CONTACT (parsable), FALSE);
-	g_return_val_if_fail (doc != NULL, FALSE);
-	g_return_val_if_fail (node != NULL, FALSE);
-
-	self = GDATA_CONTACTS_CONTACT (parsable);
-
-	if (xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
 		/* app:edited */
 		/* TODO: Should be in GDataEntry? */
 		xmlChar *edited = xmlNodeListGetString (doc, node->children, TRUE);
@@ -309,82 +304,90 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			return FALSE;
 		}
 		g_free (edited);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "name") == 0) {
-		/* gd:name */
-		GDataGDName *name = GDATA_GD_NAME (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_NAME, doc, node, NULL, error));
-		if (name == NULL)
-			return FALSE;
-
-		if (self->priv->name != NULL)
-			g_object_unref (self->priv->name);
-		self->priv->name = name;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "email") == 0) {
-		/* gd:email */
-		GDataGDEmailAddress *email = GDATA_GD_EMAIL_ADDRESS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_EMAIL_ADDRESS, doc,
-													node, NULL, error));
-		if (email == NULL)
-			return FALSE;
-
-		gdata_contacts_contact_add_email_address (self, email);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "im") == 0) {
-		/* gd:im */
-		GDataGDIMAddress *im = GDATA_GD_IM_ADDRESS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_IM_ADDRESS, doc, node, NULL, error));
-		if (im == NULL)
-			return FALSE;
-
-		gdata_contacts_contact_add_im_address (self, im);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "phoneNumber") == 0) {
-		/* gd:phoneNumber */
-		GDataGDPhoneNumber *number = GDATA_GD_PHONE_NUMBER (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_PHONE_NUMBER, doc,
-												       node, NULL, error));
-		if (number == NULL)
-			return FALSE;
-
-		gdata_contacts_contact_add_phone_number (self, number);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "structuredPostalAddress") == 0) {
-		/* gd:structuredPostalAddress â?? deprecates gd:postalAddress */
-		GDataGDPostalAddress *address = GDATA_GD_POSTAL_ADDRESS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_POSTAL_ADDRESS,
-													    doc, node, NULL, error));
-		if (address == NULL)
-			return FALSE;
-
-		gdata_contacts_contact_add_postal_address (self, address);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "organization") == 0) {
-		/* gd:organization */
-		GDataGDOrganization *organization = GDATA_GD_ORGANIZATION (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_ORGANIZATION,
-													      doc, node, NULL, error));
-		if (organization == NULL)
-			return FALSE;
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "name") == 0) {
+			/* gd:name */
+			GDataGDName *name = GDATA_GD_NAME (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_NAME, doc, node, NULL, error));
+			if (name == NULL)
+				return FALSE;
+
+			if (self->priv->name != NULL)
+				g_object_unref (self->priv->name);
+			self->priv->name = name;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "email") == 0) {
+			/* gd:email */
+			GDataGDEmailAddress *email = GDATA_GD_EMAIL_ADDRESS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_EMAIL_ADDRESS, doc,
+														node, NULL, error));
+			if (email == NULL)
+				return FALSE;
+
+			gdata_contacts_contact_add_email_address (self, email);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "im") == 0) {
+			/* gd:im */
+			GDataGDIMAddress *im = GDATA_GD_IM_ADDRESS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_IM_ADDRESS, doc, node, NULL, error));
+			if (im == NULL)
+				return FALSE;
+
+			gdata_contacts_contact_add_im_address (self, im);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "phoneNumber") == 0) {
+			/* gd:phoneNumber */
+			GDataGDPhoneNumber *number = GDATA_GD_PHONE_NUMBER (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_PHONE_NUMBER, doc,
+													       node, NULL, error));
+			if (number == NULL)
+				return FALSE;
+
+			gdata_contacts_contact_add_phone_number (self, number);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "structuredPostalAddress") == 0) {
+			/* gd:structuredPostalAddress â?? deprecates gd:postalAddress */
+			GDataGDPostalAddress *address = GDATA_GD_POSTAL_ADDRESS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_POSTAL_ADDRESS,
+														    doc, node, NULL, error));
+			if (address == NULL)
+				return FALSE;
+
+			gdata_contacts_contact_add_postal_address (self, address);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "organization") == 0) {
+			/* gd:organization */
+			GDataGDOrganization *organization = GDATA_GD_ORGANIZATION (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_ORGANIZATION,
+														      doc, node, NULL, error));
+			if (organization == NULL)
+				return FALSE;
+
+			gdata_contacts_contact_add_organization (self, organization);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "extendedProperty") == 0) {
+			/* gd:extendedProperty */
+			xmlChar *name, *value;
+			xmlBuffer *buffer = NULL;
+
+			name = xmlGetProp (node, (xmlChar*) "name");
+			if (name == NULL)
+				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");
+			if (value == NULL) {
+				xmlNode *child_node;
+
+				/* Use the element's content instead (arbitrary XML) */
+				buffer = xmlBufferCreate ();
+				for (child_node = node->children; child_node != NULL; child_node = child_node->next)
+					xmlNodeDump (buffer, doc, child_node, 0, 0);
+				value = (xmlChar*) xmlBufferContent (buffer);
+			}
 
-		gdata_contacts_contact_add_organization (self, organization);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "extendedProperty") == 0) {
-		/* gd:extendedProperty */
-		xmlChar *name, *value;
-		xmlBuffer *buffer = NULL;
-
-		name = xmlGetProp (node, (xmlChar*) "name");
-		if (name == NULL)
-			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");
-		if (value == NULL) {
-			xmlNode *child_node;
-
-			/* Use the element's content instead (arbitrary XML) */
-			buffer = xmlBufferCreate ();
-			for (child_node = node->children; child_node != NULL; child_node = child_node->next)
-				xmlNodeDump (buffer, doc, child_node, 0, 0);
-			value = (xmlChar*) xmlBufferContent (buffer);
+			gdata_contacts_contact_set_extended_property (self, (gchar*) name, (gchar*) value);
+
+			if (buffer != NULL)
+				xmlBufferFree (buffer);
+			else
+				g_free (value);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "deleted") == 0) {
+			/* gd:deleted */
+			self->priv->deleted = TRUE;
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_contacts_contact_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-
-		gdata_contacts_contact_set_extended_property (self, (gchar*) name, (gchar*) value);
-
-		if (buffer != NULL)
-			xmlBufferFree (buffer);
-		else
-			g_free (value);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "groupMembershipInfo") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/contact/2008";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "groupMembershipInfo") == 0) {
 		/* gContact:groupMembershipInfo */
 		xmlChar *href, *deleted;
 		gboolean deleted_bool;
@@ -408,9 +411,6 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 		/* Insert it into the hash table */
 		g_hash_table_insert (self->priv->groups, (gchar*) href, GUINT_TO_POINTER (deleted_bool));
-	} else if (xmlStrcmp (node->name, (xmlChar*) "deleted") == 0) {
-		/* gd:deleted */
-		self->priv->deleted = TRUE;
 	} else {
 		/* If we haven't yet found a photo, check to see if it's a photo <link> element */
 		if (self->priv->photo_etag == NULL && xmlStrcmp (node->name, (xmlChar*) "link") == 0) {
@@ -423,10 +423,7 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			xmlFree (rel);
 		}
 
-		if (GDATA_PARSABLE_CLASS (gdata_contacts_contact_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-			/* Error! */
-			return FALSE;
-		}
+		return GDATA_PARSABLE_CLASS (gdata_contacts_contact_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/documents/gdata-documents-entry.c b/gdata/services/documents/gdata-documents-entry.c
index ab33fe5..ebca181 100644
--- a/gdata/services/documents/gdata-documents-entry.c
+++ b/gdata/services/documents/gdata-documents-entry.c
@@ -203,7 +203,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataDocumentsEntry *self = GDATA_DOCUMENTS_ENTRY (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
 		xmlChar *edited = xmlNodeListGetString (doc, node->children, TRUE);
 		if (g_time_val_from_iso8601 ((gchar*) edited, &(self->priv->edited)) == FALSE) {
 			gdata_parser_error_not_iso8601_format (node, (gchar*) edited, error);
@@ -211,15 +212,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			return FALSE;
 		}
 		xmlFree (edited);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "lastViewed") == 0) {
-		xmlChar *last_viewed = xmlNodeListGetString (doc, node->children, TRUE);
-		if (g_time_val_from_iso8601 ((gchar*) last_viewed, &(self->priv->last_viewed)) == FALSE) {
-			gdata_parser_error_not_iso8601_format (node, (gchar*) last_viewed, error);
-			xmlFree (last_viewed);
-			return FALSE;
-		}
-		xmlFree (last_viewed);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "writersCanInvite") ==  0) {
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/docs/2007";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "writersCanInvite") ==  0) {
 		xmlChar *writers_can_invite = xmlGetProp (node, (xmlChar*) "value");
 		if (xmlStrcmp (writers_can_invite, (xmlChar*) "true") == 0) {
 			self->priv->writers_can_invite = TRUE;
@@ -231,47 +225,58 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			return FALSE;
 		}
 		xmlFree (writers_can_invite);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "deleted") ==  0) {
-		/* <gd:deleted> */
-		/* Note that it doesn't have any parameters, so we unconditionally set priv->is_deleted to TRUE */
-		self->priv->is_deleted = TRUE;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "resourceId") ==  0) {
-		gchar **document_id_parts;
-		xmlChar *resource_id;
-
-		if (self->priv->document_id != NULL)
-			return gdata_parser_error_duplicate_element (node, error);
-
-		resource_id = xmlNodeListGetString (doc, node->children, TRUE);
-		if (resource_id == NULL || *resource_id == '\0') {
-			xmlFree (resource_id);
-			return gdata_parser_error_required_content_missing (node, error);
-		}
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "lastViewed") == 0) {
+			xmlChar *last_viewed = xmlNodeListGetString (doc, node->children, TRUE);
+			if (g_time_val_from_iso8601 ((gchar*) last_viewed, &(self->priv->last_viewed)) == FALSE) {
+				gdata_parser_error_not_iso8601_format (node, (gchar*) last_viewed, error);
+				xmlFree (last_viewed);
+				return FALSE;
+			}
+			xmlFree (last_viewed);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "deleted") ==  0) {
+			/* <gd:deleted> */
+			/* Note that it doesn't have any parameters, so we unconditionally set priv->is_deleted to TRUE */
+			self->priv->is_deleted = TRUE;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "resourceId") ==  0) {
+			gchar **document_id_parts;
+			xmlChar *resource_id;
+
+			if (self->priv->document_id != NULL)
+				return gdata_parser_error_duplicate_element (node, error);
+
+			resource_id = xmlNodeListGetString (doc, node->children, TRUE);
+			if (resource_id == NULL || *resource_id == '\0') {
+				xmlFree (resource_id);
+				return gdata_parser_error_required_content_missing (node, error);
+			}
 
-		document_id_parts = g_strsplit ((gchar*) resource_id, ":", 2);
-		if (document_id_parts == NULL) {
-			gdata_parser_error_unknown_content (node, (gchar*) resource_id, error);
+			document_id_parts = g_strsplit ((gchar*) resource_id, ":", 2);
+			if (document_id_parts == NULL) {
+				gdata_parser_error_unknown_content (node, (gchar*) resource_id, error);
+				xmlFree (resource_id);
+				return FALSE;
+			}
 			xmlFree (resource_id);
-			return FALSE;
-		}
-		xmlFree (resource_id);
 
-		self->priv->document_id = g_strdup (document_id_parts[1]);
-		g_strfreev (document_id_parts);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "feedLink") ==  0) {
-		GDataLink *link = GDATA_LINK (_gdata_parsable_new_from_xml_node (GDATA_TYPE_LINK, doc, node, NULL, error));
-		if (link == NULL)
-			return FALSE;
-		gdata_entry_add_link (GDATA_ENTRY (self), link);
-		g_object_unref (link);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "lastModifiedBy") ==  0) {
-		GDataAuthor *last_modified_by = GDATA_AUTHOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_AUTHOR, doc, node, NULL, error));
-		if (last_modified_by == NULL)
-			return FALSE;
-		self->priv->last_modified_by = last_modified_by;
-	} else if (GDATA_PARSABLE_CLASS (gdata_documents_entry_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+			self->priv->document_id = g_strdup (document_id_parts[1]);
+			g_strfreev (document_id_parts);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "feedLink") ==  0) {
+			GDataLink *link = GDATA_LINK (_gdata_parsable_new_from_xml_node (GDATA_TYPE_LINK, doc, node, NULL, error));
+			if (link == NULL)
+				return FALSE;
+			gdata_entry_add_link (GDATA_ENTRY (self), link);
+			g_object_unref (link);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "lastModifiedBy") ==  0) {
+			GDataAuthor *last_modified_by = GDATA_AUTHOR (_gdata_parsable_new_from_xml_node (GDATA_TYPE_AUTHOR, doc, node, NULL, error));
+			if (last_modified_by == NULL)
+				return FALSE;
+			self->priv->last_modified_by = last_modified_by;
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_documents_entry_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_documents_entry_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/documents/gdata-documents-feed.c b/gdata/services/documents/gdata-documents-feed.c
index df62f45..cac9951 100644
--- a/gdata/services/documents/gdata-documents-feed.c
+++ b/gdata/services/documents/gdata-documents-feed.c
@@ -94,7 +94,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataDocumentsFeed *self = GDATA_DOCUMENTS_FEED (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "entry") == 0) {
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2005/Atom";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "entry") == 0) {
 		GDataEntry *entry = NULL;
 		gchar *kind = get_kind (doc, node);
 
@@ -119,10 +120,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* Call the progress callback in the main thread */
 		_gdata_feed_call_progress_callback (GDATA_FEED (self), user_data, entry);
 		_gdata_feed_add_entry (GDATA_FEED (self), entry);
-	} else if (GDATA_PARSABLE_CLASS (gdata_documents_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+
+		return TRUE;
 	}
 
-	return TRUE;
+	return GDATA_PARSABLE_CLASS (gdata_documents_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 }
diff --git a/gdata/services/picasaweb/gdata-picasaweb-album.c b/gdata/services/picasaweb/gdata-picasaweb-album.c
index 0d833f9..ebf20e4 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-album.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-album.c
@@ -549,7 +549,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataPicasaWebAlbum *self = GDATA_PICASAWEB_ALBUM (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
+	if (gdata_parser_is_namespace (node, "http://search.yahoo.com/mrss/";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
 		/* media:group */
 		GDataMediaGroup *group = GDATA_MEDIA_GROUP (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_GROUP, doc, node, NULL, error));
 		if (group == NULL)
@@ -561,7 +562,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			g_object_unref (self->priv->media_group);
 
 		self->priv->media_group = group;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://www.georss.org/georss";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
 		/* georss:where */
 		GDataGeoRSSWhere *where = GDATA_GEORSS_WHERE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GEORSS_WHERE, doc, node, NULL, error));
 		if (where == NULL)
@@ -571,21 +573,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			g_object_unref (self->priv->georss_where);
 
 		self->priv->georss_where = where;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
-		/* gphoto:user */
-		xmlChar *user = xmlNodeListGetString (doc, node->children, TRUE);
-		if (user == NULL || *user == '\0')
-			return gdata_parser_error_required_content_missing (node, error);
-		g_free (self->priv->user);
-		self->priv->user = (gchar*) user;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "nickname") == 0) {
-		/* gphoto:nickname */
-		xmlChar *nickname = xmlNodeListGetString (doc, node->children, TRUE);
-		if (nickname == NULL || *nickname == '\0')
-			return gdata_parser_error_required_content_missing (node, error);
-		g_free (self->priv->nickname);
-		self->priv->nickname = (gchar*) nickname;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	           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) {
@@ -595,89 +584,105 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			return FALSE;
 		}
 		xmlFree (edited);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "location") == 0) {
-		/* gphoto:location */
-		g_free (self->priv->location);
-		self->priv->location = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
-		/* gphoto:access */
-		xmlChar *access = xmlNodeListGetString (doc, node->children, TRUE);
-		if (xmlStrcmp (access, (xmlChar*) "public") == 0) {
-			gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PUBLIC);
-		} else if (xmlStrcmp (access, (xmlChar*) "private") == 0) {
-			gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PRIVATE);
-		} else {
-			gdata_parser_error_unknown_content (node, (gchar*) access, error);
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/photos/2007";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
+			/* gphoto:user */
+			xmlChar *user = xmlNodeListGetString (doc, node->children, TRUE);
+			if (user == NULL || *user == '\0')
+				return gdata_parser_error_required_content_missing (node, error);
+			g_free (self->priv->user);
+			self->priv->user = (gchar*) user;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "nickname") == 0) {
+			/* gphoto:nickname */
+			xmlChar *nickname = xmlNodeListGetString (doc, node->children, TRUE);
+			if (nickname == NULL || *nickname == '\0')
+				return gdata_parser_error_required_content_missing (node, error);
+			g_free (self->priv->nickname);
+			self->priv->nickname = (gchar*) nickname;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "location") == 0) {
+			/* gphoto:location */
+			g_free (self->priv->location);
+			self->priv->location = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
+			/* gphoto:access */
+			xmlChar *access = xmlNodeListGetString (doc, node->children, TRUE);
+			if (xmlStrcmp (access, (xmlChar*) "public") == 0) {
+				gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PUBLIC);
+			} else if (xmlStrcmp (access, (xmlChar*) "private") == 0) {
+				gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PRIVATE);
+			} else {
+				gdata_parser_error_unknown_content (node, (gchar*) access, error);
+			}
 			xmlFree (access);
-			return FALSE;
-		}
-		xmlFree (access);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
-		/* gphoto:timestamp */
-		xmlChar *timestamp_str;
-		guint64 milliseconds;
-		GTimeVal timestamp;
-
-		timestamp_str = xmlNodeListGetString (doc, node->children, TRUE);
-		milliseconds = g_ascii_strtoull ((gchar*) timestamp_str, NULL, 10);
-		xmlFree (timestamp_str);
-
-		timestamp.tv_sec = (glong) (milliseconds / 1000);
-		timestamp.tv_usec = (glong) ((milliseconds % 1000) * 1000);
-
-		gdata_picasaweb_album_set_timestamp (self, &timestamp);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "numphotos") == 0) {
-		/* gphoto:numphotos */
-		xmlChar *num_photos = xmlNodeListGetString (doc, node->children, TRUE);
-		if (num_photos == NULL || *num_photos == '\0') {
+		} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
+			/* gphoto:timestamp */
+			xmlChar *timestamp_str;
+			guint64 milliseconds;
+			GTimeVal timestamp;
+
+			timestamp_str = xmlNodeListGetString (doc, node->children, TRUE);
+			milliseconds = g_ascii_strtoull ((gchar*) timestamp_str, NULL, 10);
+			xmlFree (timestamp_str);
+
+			timestamp.tv_sec = (glong) (milliseconds / 1000);
+			timestamp.tv_usec = (glong) ((milliseconds % 1000) * 1000);
+
+			gdata_picasaweb_album_set_timestamp (self, &timestamp);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "numphotos") == 0) {
+			/* gphoto:numphotos */
+			xmlChar *num_photos = xmlNodeListGetString (doc, node->children, TRUE);
+			if (num_photos == NULL || *num_photos == '\0') {
+				xmlFree (num_photos);
+				return gdata_parser_error_required_content_missing (node, error);
+			}
+
+			self->priv->num_photos = strtoul ((char*) num_photos, NULL, 10);
 			xmlFree (num_photos);
-			return gdata_parser_error_required_content_missing (node, error);
-		}
-
-		self->priv->num_photos = strtoul ((char*) num_photos, NULL, 10);
-		xmlFree (num_photos);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "numphotosremaining") == 0) {
-		/* gphoto:numphotosremaining */
-		xmlChar *num_photos_remaining = xmlNodeListGetString (doc, node->children, TRUE);
-		if (num_photos_remaining == NULL || *num_photos_remaining == '\0') {
+		} else if (xmlStrcmp (node->name, (xmlChar*) "numphotosremaining") == 0) {
+			/* gphoto:numphotosremaining */
+			xmlChar *num_photos_remaining = xmlNodeListGetString (doc, node->children, TRUE);
+			if (num_photos_remaining == NULL || *num_photos_remaining == '\0') {
+				xmlFree (num_photos_remaining);
+				return gdata_parser_error_required_content_missing (node, error);
+			}
+
+			self->priv->num_photos_remaining = strtoul ((char*) num_photos_remaining, NULL, 10);
 			xmlFree (num_photos_remaining);
-			return gdata_parser_error_required_content_missing (node, error);
-		}
-
-		self->priv->num_photos_remaining = strtoul ((char*) num_photos_remaining, NULL, 10);
-		xmlFree (num_photos_remaining);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "bytesUsed") == 0) {
-		/* gphoto:bytesUsed */
-		xmlChar *bytes_used = xmlNodeListGetString (doc, node->children, TRUE);
-		if (bytes_used == NULL || *bytes_used == '\0') {
+		} else if (xmlStrcmp (node->name, (xmlChar*) "bytesUsed") == 0) {
+			/* gphoto:bytesUsed */
+			xmlChar *bytes_used = xmlNodeListGetString (doc, node->children, TRUE);
+			if (bytes_used == NULL || *bytes_used == '\0') {
+				xmlFree (bytes_used);
+				return gdata_parser_error_required_content_missing (node, error);
+			}
+
+			self->priv->bytes_used = strtol ((char*) bytes_used, NULL, 10);
 			xmlFree (bytes_used);
-			return gdata_parser_error_required_content_missing (node, error);
-		}
-
-		self->priv->bytes_used = strtol ((char*) bytes_used, NULL, 10);
-		xmlFree (bytes_used);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "commentingEnabled") == 0) {
-		/* gphoto:commentingEnabled */
-		xmlChar *commenting_enabled = xmlNodeListGetString (doc, node->children, TRUE);
-		if (commenting_enabled == NULL || *commenting_enabled == '\0') {
+		} else if (xmlStrcmp (node->name, (xmlChar*) "commentingEnabled") == 0) {
+			/* gphoto:commentingEnabled */
+			xmlChar *commenting_enabled = xmlNodeListGetString (doc, node->children, TRUE);
+			if (commenting_enabled == NULL || *commenting_enabled == '\0') {
+				xmlFree (commenting_enabled);
+				return gdata_parser_error_required_content_missing (node, error);
+			}
+
+			gdata_picasaweb_album_set_is_commenting_enabled (self, (xmlStrcmp (commenting_enabled, (xmlChar*) "true") == 0) ? TRUE : FALSE);
 			xmlFree (commenting_enabled);
-			return gdata_parser_error_required_content_missing (node, error);
-		}
-
-		gdata_picasaweb_album_set_is_commenting_enabled (self, (xmlStrcmp (commenting_enabled, (xmlChar*) "true") == 0) ? TRUE : FALSE);
-		xmlFree (commenting_enabled);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "commentCount") == 0) {
-		xmlChar *comment_count = xmlNodeListGetString (doc, node->children, TRUE);
-		if (comment_count == NULL || *comment_count == '\0') {
+		} else if (xmlStrcmp (node->name, (xmlChar*) "commentCount") == 0) {
+			/* gphoto:commentCount */
+			xmlChar *comment_count = xmlNodeListGetString (doc, node->children, TRUE);
+			if (comment_count == NULL || *comment_count == '\0') {
+				xmlFree (comment_count);
+				return gdata_parser_error_required_content_missing (node, error);
+			}
+
+			self->priv->comment_count = strtoul ((char*) comment_count, NULL, 10);
 			xmlFree (comment_count);
-			return gdata_parser_error_required_content_missing (node, error);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_picasaweb_album_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-
-		self->priv->comment_count = strtoul ((char*) comment_count, NULL, 10);
-		xmlFree (comment_count);
-	} else if (GDATA_PARSABLE_CLASS (gdata_picasaweb_album_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_picasaweb_album_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/picasaweb/gdata-picasaweb-feed.c b/gdata/services/picasaweb/gdata-picasaweb-feed.c
index 01e6b0f..c297ef6 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-feed.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-feed.c
@@ -58,60 +58,63 @@ gdata_picasaweb_feed_init (GDataPicasaWebFeed *self)
 static gboolean
 parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
 {
-	if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
-		/* gphoto:user */
-		/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "nickname") == 0) {
-		/* gphoto:nickname */
-		/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "quotacurrent") == 0) {
-		/* gphoto:quota-current */
-		/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "quotalimit") == 0) {
-		/* gphoto:quota-limit */
-		/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "maxPhotosPerAlbum") == 0) {
-		/* gphoto:max-photos-per-album */
-		/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "thumbnail") == 0) {
-		/* gphoto:thumbnail */
-		/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "allowDownloads") == 0) {
-		/* gphoto:allowDownloads */
-		/* Not part of public API so we're capturing and ignoring for now.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "allowPrints") == 0) {
-		/* gphoto:allowPrints */
-		/* Not part of public API so we're capturing and ignoring for now.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0 && xmlStrcmp (node->ns->href, (xmlChar*) "http://schemas.google.com/photos/2007";) == 0) {
-		/* gphoto:id */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "rights") == 0) {
-		/* gphoto:rights */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "location") == 0) {
-		/* gphoto:location */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
-		/* gphoto:access */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
-		/* gphoto:timestamp */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "numphotos") == 0) {
-		/* gphoto:numphotos */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "numphotosremaining") == 0) {
-		/* gphoto:numphotosremaining */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "bytesUsed") == 0) {
-		/* gphoto:bytesUsed */
-		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/photos/2007";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
+			/* gphoto:user */
+			/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "nickname") == 0) {
+			/* gphoto:nickname */
+			/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "quotacurrent") == 0) {
+			/* gphoto:quota-current */
+			/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "quotalimit") == 0) {
+			/* gphoto:quota-limit */
+			/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "maxPhotosPerAlbum") == 0) {
+			/* gphoto:max-photos-per-album */
+			/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "thumbnail") == 0) {
+			/* gphoto:thumbnail */
+			/* From user's feed of album entries.  Redundant with user entry represented by GDataPicasaWebUser.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "allowDownloads") == 0) {
+			/* gphoto:allowDownloads */
+			/* Not part of public API so we're capturing and ignoring for now.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "allowPrints") == 0) {
+			/* gphoto:allowPrints */
+			/* Not part of public API so we're capturing and ignoring for now.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0 && xmlStrcmp (node->ns->href, (xmlChar*) "http://schemas.google.com/photos/2007";) == 0) {
+			/* gphoto:id */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "rights") == 0) {
+			/* gphoto:rights */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "location") == 0) {
+			/* gphoto:location */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
+			/* gphoto:access */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
+			/* gphoto:timestamp */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "numphotos") == 0) {
+			/* gphoto:numphotos */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "numphotosremaining") == 0) {
+			/* gphoto:numphotosremaining */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "bytesUsed") == 0) {
+			/* gphoto:bytesUsed */
+			/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_picasaweb_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else if (gdata_parser_is_namespace (node, "http://www.georss.org/georss";) == TRUE && xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
 		/* georss:where */
 		/* From album's feed of file entries.  Redundant with album entries represented by GDataPicasaWebAlbum.  Capturing and ignoring.  See bgo #589858. */
-	} else if (GDATA_PARSABLE_CLASS (gdata_picasaweb_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_picasaweb_feed_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/picasaweb/gdata-picasaweb-file.c b/gdata/services/picasaweb/gdata-picasaweb-file.c
index a3a90b6..b343071 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-file.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-file.c
@@ -795,7 +795,19 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataPicasaWebFile *self = GDATA_PICASAWEB_FILE (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	    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 (node, (gchar*) edited, error);
+			xmlFree (edited);
+			return FALSE;
+		}
+		xmlFree (edited);
+	} else if (gdata_parser_is_namespace (node, "http://search.yahoo.com/mrss/";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
 		/* media:group */
 		GDataMediaGroup *group = GDATA_MEDIA_GROUP (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_GROUP, doc, node, NULL, error));
 		if (group == NULL)
@@ -807,7 +819,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			g_object_unref (self->priv->media_group);
 
 		self->priv->media_group = group;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://www.georss.org/georss";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
 		/* georss:where */
 		GDataGeoRSSWhere *where = GDATA_GEORSS_WHERE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GEORSS_WHERE, doc, node, NULL, error));
 		if (where == NULL)
@@ -817,7 +830,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			g_object_unref (self->priv->georss_where);
 
 		self->priv->georss_where = where;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "tags") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/photos/exif/2007";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "tags") == 0) {
 		/* exif:tags */
 		GDataExifTags *tags = GDATA_EXIF_TAGS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_EXIF_TAGS, doc, node, NULL, error));
 		if (tags == NULL)
@@ -827,96 +841,89 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			g_object_unref (self->priv->exif_tags);
 
 		self->priv->exif_tags = tags;
-	} 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 (node, (gchar*) edited, error);
-			xmlFree (edited);
-			return FALSE;
-		}
-		xmlFree (edited);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "imageVersion") == 0) {
-		/* gphoto:imageVersion */
-		g_free (self->priv->version);
-		self->priv->version = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "position") == 0) {
-		/* gphoto:position */
-		xmlChar *position_str = xmlNodeListGetString (doc, node->children, TRUE);
-		gdata_picasaweb_file_set_position (self, g_ascii_strtod ((gchar*) position_str, NULL));
-		xmlFree (position_str);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "albumid") == 0) {
-		/* gphoto:album_id */
-		self->priv->album_id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "width") == 0) {
-		/* gphoto:width */
-		xmlChar *width = xmlNodeListGetString (doc, node->children, TRUE);
-		self->priv->width = strtoul ((gchar*) width, NULL, 10);
-		xmlFree (width);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "height") == 0) {
-		/* gphoto:height */
-		xmlChar *height = xmlNodeListGetString (doc, node->children, TRUE);
-		self->priv->height = strtoul ((gchar*) height, NULL, 10);
-		xmlFree (height);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "size") == 0) {
-		/* gphoto:size */
-		xmlChar *size = xmlNodeListGetString (doc, node->children, TRUE);
-		self->priv->size = strtoul ((gchar*) size, NULL, 10);
-		xmlFree (size);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "client") == 0) {
-		/* gphoto:client */
-		self->priv->client = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "checksum") == 0) {
-		/* gphoto:checksum */
-		self->priv->checksum = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
-		/* gphoto:timestamp */
-		xmlChar *timestamp_str;
-		guint64 milliseconds;
-		GTimeVal timestamp;
-
-		timestamp_str = xmlNodeListGetString (doc, node->children, TRUE);
-		milliseconds = g_ascii_strtoull ((gchar*) timestamp_str, NULL, 10);
-		xmlFree (timestamp_str);
-
-		timestamp.tv_sec = (glong) (milliseconds / 1000);
-		timestamp.tv_usec = (glong) ((milliseconds % 1000) * 1000);
-
-		gdata_picasaweb_file_set_timestamp (self, &timestamp);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "commentingEnabled") == 0) {
-		/* gphoto:commentingEnabled */
-		xmlChar *is_commenting_enabled = xmlNodeListGetString (doc, node->children, TRUE);
-		if (is_commenting_enabled == NULL)
-			return gdata_parser_error_required_content_missing (node, error);
-		self->priv->is_commenting_enabled = (xmlStrcmp (is_commenting_enabled, (xmlChar*) "true") == 0 ? TRUE : FALSE);
-		xmlFree (is_commenting_enabled);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "commentCount") == 0) {
-		/* gphoto:commentCount */
-		xmlChar *comment_count = xmlNodeListGetString (doc, node->children, TRUE);
-		self->priv->comment_count = strtoul ((gchar*) comment_count, NULL, 10);
-		xmlFree (comment_count);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "videostatus") == 0) {
-		/* gphoto:videostatus */
-		xmlChar *video_status = xmlNodeListGetString (doc, node->children, TRUE);
-		if (self->priv->video_status != NULL) {
-			xmlFree (video_status);
-			return gdata_parser_error_duplicate_element (node, error);
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/photos/2007";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "imageVersion") == 0) {
+			/* gphoto:imageVersion */
+			g_free (self->priv->version);
+			self->priv->version = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "position") == 0) {
+			/* gphoto:position */
+			xmlChar *position_str = xmlNodeListGetString (doc, node->children, TRUE);
+			gdata_picasaweb_file_set_position (self, g_ascii_strtod ((gchar*) position_str, NULL));
+			xmlFree (position_str);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "albumid") == 0) {
+			/* gphoto:album_id */
+			self->priv->album_id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "width") == 0) {
+			/* gphoto:width */
+			xmlChar *width = xmlNodeListGetString (doc, node->children, TRUE);
+			self->priv->width = strtoul ((gchar*) width, NULL, 10);
+			xmlFree (width);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "height") == 0) {
+			/* gphoto:height */
+			xmlChar *height = xmlNodeListGetString (doc, node->children, TRUE);
+			self->priv->height = strtoul ((gchar*) height, NULL, 10);
+			xmlFree (height);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "size") == 0) {
+			/* gphoto:size */
+			xmlChar *size = xmlNodeListGetString (doc, node->children, TRUE);
+			self->priv->size = strtoul ((gchar*) size, NULL, 10);
+			xmlFree (size);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "client") == 0) {
+			/* gphoto:client */
+			self->priv->client = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "checksum") == 0) {
+			/* gphoto:checksum */
+			self->priv->checksum = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
+			/* gphoto:timestamp */
+			xmlChar *timestamp_str;
+			guint64 milliseconds;
+			GTimeVal timestamp;
+
+			timestamp_str = xmlNodeListGetString (doc, node->children, TRUE);
+			milliseconds = g_ascii_strtoull ((gchar*) timestamp_str, NULL, 10);
+			xmlFree (timestamp_str);
+
+			timestamp.tv_sec = (glong) (milliseconds / 1000);
+			timestamp.tv_usec = (glong) ((milliseconds % 1000) * 1000);
+
+			gdata_picasaweb_file_set_timestamp (self, &timestamp);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "commentingEnabled") == 0) {
+			/* gphoto:commentingEnabled */
+			xmlChar *is_commenting_enabled = xmlNodeListGetString (doc, node->children, TRUE);
+			if (is_commenting_enabled == NULL)
+				return gdata_parser_error_required_content_missing (node, error);
+			self->priv->is_commenting_enabled = (xmlStrcmp (is_commenting_enabled, (xmlChar*) "true") == 0 ? TRUE : FALSE);
+			xmlFree (is_commenting_enabled);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "commentCount") == 0) {
+			/* gphoto:commentCount */
+			xmlChar *comment_count = xmlNodeListGetString (doc, node->children, TRUE);
+			self->priv->comment_count = strtoul ((gchar*) comment_count, NULL, 10);
+			xmlFree (comment_count);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "videostatus") == 0) {
+			/* gphoto:videostatus */
+			xmlChar *video_status = xmlNodeListGetString (doc, node->children, TRUE);
+			if (self->priv->video_status != NULL) {
+				xmlFree (video_status);
+				return gdata_parser_error_duplicate_element (node, error);
+			}
+			self->priv->video_status = (gchar*) video_status;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
+			/* gphoto:access */
+			/* Visibility is already obtained through the album. When PicasaWeb supports per-file access restrictions,
+			   we'll expose this property. Until then, we'll catch this to suppress the Unhandled XML warning.
+			   See https://bugzilla.gnome.org/show_bug.cgi?id=589858 */
+		} else if (xmlStrcmp (node->name, (xmlChar*) "rotation") == 0) {
+			/* gphoto:rotation */
+			xmlChar *rotation = xmlNodeListGetString (doc, node->children, TRUE);
+			gdata_picasaweb_file_set_rotation (self, strtoul ((gchar*) rotation, NULL, 10));
+			xmlFree (rotation);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_picasaweb_file_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-		self->priv->video_status = (gchar*) video_status;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
-		/* gphoto:access */
-		/* Visibility is already obtained through the album. When PicasaWeb supports per-file access restrictions,
-		   we'll expose this property. Until then, we'll catch this to suppress the Unhandled XML warning.
-		   See https://bugzilla.gnome.org/show_bug.cgi?id=589858 */
-	} else if (xmlStrcmp (node->name, (xmlChar*) "rotation") == 0) {
-		/* gphoto:rotation */
-		xmlChar *rotation = xmlNodeListGetString (doc, node->children, TRUE);
-		gdata_picasaweb_file_set_rotation (self, strtoul ((gchar*) rotation, NULL, 10));
-		xmlFree (rotation);
-	} else if (GDATA_PARSABLE_CLASS (gdata_picasaweb_file_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_picasaweb_file_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/picasaweb/gdata-picasaweb-user.c b/gdata/services/picasaweb/gdata-picasaweb-user.c
index 7d61000..c848f99 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-user.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-user.c
@@ -220,6 +220,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataPicasaWebUser *self = GDATA_PICASAWEB_USER (parsable);
 
+	if (gdata_parser_is_namespace (node, "http://schemas.google.com/photos/2007";) == FALSE)
+		return GDATA_PARSABLE_CLASS (gdata_picasaweb_user_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+
 	if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
 		/* gphoto:user */
 		xmlChar *user = xmlNodeListGetString (doc, node->children, TRUE);
@@ -270,10 +273,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* Not part of public API so we're capturing and ignoring for now.  See bgo #589858. */
 	} else if (xmlStrcmp (node->name, (xmlChar*) "x-allowPrints") == 0) { /* RHSTODO: see if this comes with the user */
 		/* gphoto:allowPrints */
-		/* Not part of public API so we're capturing and ignoring for now.  See bgo #589858. */
-	} else if (GDATA_PARSABLE_CLASS (gdata_picasaweb_user_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+		/* TODO: Not part of public API so we're capturing and ignoring for now.  See bgo #589858. */
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_picasaweb_user_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/youtube/gdata-youtube-control.c b/gdata/services/youtube/gdata-youtube-control.c
index d909729..e7ccd8a 100644
--- a/gdata/services/youtube/gdata-youtube-control.c
+++ b/gdata/services/youtube/gdata-youtube-control.c
@@ -98,7 +98,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataYouTubeControl *self = GDATA_YOUTUBE_CONTROL (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "draft") == 0) {
+	if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "draft") == 0) {
 		/* app:draft */
 		xmlChar *draft = xmlNodeListGetString (doc, node, TRUE);
 		if (xmlStrcmp (draft, (xmlChar*) "no") == 0)
@@ -106,7 +107,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		else
 			self->priv->is_draft = TRUE;
 		xmlFree (draft);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "state") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://gdata.youtube.com/schemas/2007";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "state") == 0) {
 		/* yt:state */
 		GDataYouTubeState *state = GDATA_YOUTUBE_STATE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_YOUTUBE_STATE, doc, node, NULL, error));
 		if (state == NULL)
@@ -118,9 +120,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		}
 
 		self->priv->state = state;
-	} else if (GDATA_PARSABLE_CLASS (gdata_youtube_control_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_youtube_control_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/youtube/gdata-youtube-group.c b/gdata/services/youtube/gdata-youtube-group.c
index adeae5f..42af611 100644
--- a/gdata/services/youtube/gdata-youtube-group.c
+++ b/gdata/services/youtube/gdata-youtube-group.c
@@ -92,75 +92,80 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataYouTubeGroup *self = GDATA_YOUTUBE_GROUP (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
-		/* media:content */
-		GDataYouTubeContent *content = GDATA_YOUTUBE_CONTENT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_YOUTUBE_CONTENT, doc,
-													 node, NULL, error));
-		if (content == NULL)
-			return FALSE;
-
-		_gdata_media_group_add_content (GDATA_MEDIA_GROUP (self), GDATA_MEDIA_CONTENT (content));
-	} else if (xmlStrcmp (node->name, (xmlChar*) "credit") == 0) {
-		/* media:credit */
-		GDataYouTubeCredit *credit = GDATA_YOUTUBE_CREDIT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_YOUTUBE_CREDIT, doc,
-												      node, NULL, error));
-		if (credit == NULL)
-			return FALSE;
-
-		if (gdata_media_group_get_credit (GDATA_MEDIA_GROUP (self)) != NULL) {
-			g_object_unref (credit);
-			return gdata_parser_error_duplicate_element (node, error);
+	if (gdata_parser_is_namespace (node, "http://search.yahoo.com/mrss/";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
+			/* media:content */
+			GDataYouTubeContent *content = GDATA_YOUTUBE_CONTENT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_YOUTUBE_CONTENT, doc,
+														 node, NULL, error));
+			if (content == NULL)
+				return FALSE;
+
+			_gdata_media_group_add_content (GDATA_MEDIA_GROUP (self), GDATA_MEDIA_CONTENT (content));
+		} else if (xmlStrcmp (node->name, (xmlChar*) "credit") == 0) {
+			/* media:credit */
+			GDataYouTubeCredit *credit = GDATA_YOUTUBE_CREDIT (_gdata_parsable_new_from_xml_node (GDATA_TYPE_YOUTUBE_CREDIT, doc,
+													      node, NULL, error));
+			if (credit == NULL)
+				return FALSE;
+
+			if (gdata_media_group_get_credit (GDATA_MEDIA_GROUP (self)) != NULL) {
+				g_object_unref (credit);
+				return gdata_parser_error_duplicate_element (node, error);
+			}
+
+			_gdata_media_group_set_credit (GDATA_MEDIA_GROUP (self), GDATA_MEDIA_CREDIT (credit));
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_youtube_group_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-
-		_gdata_media_group_set_credit (GDATA_MEDIA_GROUP (self), GDATA_MEDIA_CREDIT (credit));
-	} else if (xmlStrcmp (node->name, (xmlChar*) "duration") == 0) {
-		/* yt:duration */
-		xmlChar *duration = xmlGetProp (node, (xmlChar*) "seconds");
-		if (duration == NULL)
-			return gdata_parser_error_required_property_missing (node, "seconds", error);
-
-		self->priv->duration = strtoul ((gchar*) duration, NULL, 10);
-		xmlFree (duration);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "private") == 0) {
-		/* yt:private */
-		gdata_youtube_group_set_is_private (self, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "uploaded") == 0) {
-		/* yt:uploaded */
-		xmlChar *uploaded;
-		GTimeVal uploaded_timeval;
-
-		uploaded = xmlNodeListGetString (doc, node->children, TRUE);
-		if (g_time_val_from_iso8601 ((gchar*) uploaded, &uploaded_timeval) == FALSE) {
-			/* Error */
-			gdata_parser_error_not_iso8601_format (node, (gchar*) uploaded, error);
+	} else if (gdata_parser_is_namespace (node, "http://gdata.youtube.com/schemas/2007";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "duration") == 0) {
+			/* yt:duration */
+			xmlChar *duration = xmlGetProp (node, (xmlChar*) "seconds");
+			if (duration == NULL)
+				return gdata_parser_error_required_property_missing (node, "seconds", error);
+
+			self->priv->duration = strtoul ((gchar*) duration, NULL, 10);
+			xmlFree (duration);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "private") == 0) {
+			/* yt:private */
+			gdata_youtube_group_set_is_private (self, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "uploaded") == 0) {
+			/* yt:uploaded */
+			xmlChar *uploaded;
+			GTimeVal uploaded_timeval;
+
+			uploaded = xmlNodeListGetString (doc, node->children, TRUE);
+			if (g_time_val_from_iso8601 ((gchar*) uploaded, &uploaded_timeval) == FALSE) {
+				/* Error */
+				gdata_parser_error_not_iso8601_format (node, (gchar*) uploaded, error);
+				xmlFree (uploaded);
+				return FALSE;
+			}
 			xmlFree (uploaded);
-			return FALSE;
-		}
-		xmlFree (uploaded);
-
-		self->priv->uploaded = uploaded_timeval;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "videoid") == 0) {
-		/* yt:videoid */
-		xmlChar *video_id = xmlNodeListGetString (doc, node->children, TRUE);
-		if (self->priv->video_id != NULL) {
-			xmlFree (video_id);
-			return gdata_parser_error_duplicate_element (node, error);
-		}
-		self->priv->video_id = (gchar*) video_id;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "aspectRatio") == 0) {
-		/* yt:aspectRatio */
-		xmlChar *aspect_ratio = xmlNodeGetContent (node);
-		if (xmlStrcmp (aspect_ratio, (xmlChar*) "widescreen") == 0) {
-			gdata_youtube_group_set_aspect_ratio (self, GDATA_YOUTUBE_ASPECT_RATIO_WIDESCREEN);
-		} else {
-			gdata_parser_error_unknown_content (node, (const gchar*) aspect_ratio, error);
+
+			self->priv->uploaded = uploaded_timeval;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "videoid") == 0) {
+			/* yt:videoid */
+			xmlChar *video_id = xmlNodeListGetString (doc, node->children, TRUE);
+			if (self->priv->video_id != NULL) {
+				xmlFree (video_id);
+				return gdata_parser_error_duplicate_element (node, error);
+			}
+			self->priv->video_id = (gchar*) video_id;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "aspectRatio") == 0) {
+			/* yt:aspectRatio */
+			xmlChar *aspect_ratio = xmlNodeGetContent (node);
+			if (xmlStrcmp (aspect_ratio, (xmlChar*) "widescreen") == 0) {
+				gdata_youtube_group_set_aspect_ratio (self, GDATA_YOUTUBE_ASPECT_RATIO_WIDESCREEN);
+			} else {
+				gdata_parser_error_unknown_content (node, (const gchar*) aspect_ratio, error);
+			}
 			xmlFree (aspect_ratio);
-			return FALSE;
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_youtube_group_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 		}
-		xmlFree (aspect_ratio);
-	} else if (GDATA_PARSABLE_CLASS (gdata_youtube_group_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_youtube_group_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/services/youtube/gdata-youtube-video.c b/gdata/services/youtube/gdata-youtube-video.c
index d9f2114..cdb004a 100644
--- a/gdata/services/youtube/gdata-youtube-video.c
+++ b/gdata/services/youtube/gdata-youtube-video.c
@@ -645,7 +645,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 {
 	GDataYouTubeVideo *self = GDATA_YOUTUBE_VIDEO (parsable);
 
-	if (xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
+	if (gdata_parser_is_namespace (node, "http://search.yahoo.com/mrss/";) == TRUE &&
+	    xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
 		/* media:group */
 		GDataMediaGroup *group = GDATA_MEDIA_GROUP (_gdata_parsable_new_from_xml_node (GDATA_TYPE_YOUTUBE_GROUP, doc, node, NULL, error));
 		if (group == NULL)
@@ -657,106 +658,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		}
 
 		self->priv->media_group = group;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "rating") == 0) {
-		/* gd:rating */
-		xmlChar *min, *max, *num_raters, *average;
-		guint num_raters_uint;
-		gdouble average_double;
-
-		min = xmlGetProp (node, (xmlChar*) "min");
-		if (min == NULL)
-			return gdata_parser_error_required_property_missing (node, "min", error);
-
-		max = xmlGetProp (node, (xmlChar*) "max");
-		if (max == NULL) {
-			gdata_parser_error_required_property_missing (node, "max", error);
-			xmlFree (min);
-			return FALSE;
-		}
-
-		num_raters = xmlGetProp (node, (xmlChar*) "numRaters");
-		if (num_raters == NULL)
-			num_raters_uint = 0;
-		else
-			num_raters_uint = strtoul ((gchar*) num_raters, NULL, 10);
-		xmlFree (num_raters);
-
-		average = xmlGetProp (node, (xmlChar*) "average");
-		if (average == NULL)
-			average_double = 0;
-		else
-			average_double = g_ascii_strtod ((gchar*) average, NULL);
-		xmlFree (average);
-
-		self->priv->rating.min = strtoul ((gchar*) min, NULL, 10);
-		self->priv->rating.max = strtoul ((gchar*) max, NULL, 10);
-		self->priv->rating.count = num_raters_uint;
-		self->priv->rating.average = average_double;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "comments") == 0) {
-		/* gd:comments */
-		xmlChar *rel, *href, *count_hint, *read_only;
-		xmlNode *child_node;
-		guint count_hint_uint;
-
-		/* This is actually the child of the <comments> element */
-		child_node = node->children;
-
-		count_hint = xmlGetProp (child_node, (xmlChar*) "countHint");
-		if (count_hint == NULL)
-			count_hint_uint = 0;
-		else
-			count_hint_uint = strtoul ((gchar*) count_hint, NULL, 10);
-		xmlFree (count_hint);
-
-		read_only = xmlGetProp (child_node, (xmlChar*) "readOnly");
-		rel = xmlGetProp (child_node, (xmlChar*) "rel");
-		href = xmlGetProp (child_node, (xmlChar*) "href");
-
-		/* TODO */
-		/*gdata_gd_feed_link_free (self->priv->comments_feed_link);
-		self->priv->comments_feed_link = gdata_gd_feed_link_new ((gchar*) href, (gchar*) rel, count_hint_uint,
-									 ((xmlStrcmp (read_only, (xmlChar*) "true") == 0) ? TRUE : FALSE));*/
-
-		xmlFree (rel);
-		xmlFree (href);
-		xmlFree (read_only);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "statistics") == 0) {
-		/* yt:statistics */
-		xmlChar *view_count, *favorite_count;
-
-		/* View count */
-		view_count = xmlGetProp (node, (xmlChar*) "viewCount");
-		if (view_count == NULL)
-			return gdata_parser_error_required_property_missing (node, "viewCount", error);
-		self->priv->view_count = strtoul ((gchar*) view_count, NULL, 10);
-		xmlFree (view_count);
-
-		/* Favourite count */
-		favorite_count = xmlGetProp (node, (xmlChar*) "favoriteCount");
-		self->priv->favorite_count = (favorite_count != NULL) ? strtoul ((gchar*) favorite_count, NULL, 10) : 0;
-		xmlFree (favorite_count);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "location") == 0) {
-		/* yt:location */
-		g_free (self->priv->location);
-		self->priv->location = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "noembed") == 0) {
-		/* yt:noembed */
-		gdata_youtube_video_set_no_embed (self, TRUE);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "recorded") == 0) {
-		/* yt:recorded */
-		xmlChar *recorded;
-		GTimeVal recorded_timeval;
-
-		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 (node, (gchar*) recorded, error);
-			xmlFree (recorded);
-			return FALSE;
-		}
-		xmlFree (recorded);
-		gdata_youtube_video_set_recorded (self, &recorded_timeval);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "control") == 0) {
+	} else if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app";) == TRUE &&
+	           xmlStrcmp (node->name, (xmlChar*) "control") == 0) {
 		/* app:control */
 		GDataYouTubeControl *control = GDATA_YOUTUBE_CONTROL (_gdata_parsable_new_from_xml_node (GDATA_TYPE_YOUTUBE_CONTROL, doc,
 													 node, NULL, error));
@@ -769,9 +672,115 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		}
 
 		self->priv->youtube_control = control;
-	} else if (GDATA_PARSABLE_CLASS (gdata_youtube_video_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
-		/* Error! */
-		return FALSE;
+	} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/g/2005";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "rating") == 0) {
+			/* gd:rating */
+			xmlChar *min, *max, *num_raters, *average;
+			guint num_raters_uint;
+			gdouble average_double;
+
+			min = xmlGetProp (node, (xmlChar*) "min");
+			if (min == NULL)
+				return gdata_parser_error_required_property_missing (node, "min", error);
+
+			max = xmlGetProp (node, (xmlChar*) "max");
+			if (max == NULL) {
+				gdata_parser_error_required_property_missing (node, "max", error);
+				xmlFree (min);
+				return FALSE;
+			}
+
+			num_raters = xmlGetProp (node, (xmlChar*) "numRaters");
+			if (num_raters == NULL)
+				num_raters_uint = 0;
+			else
+				num_raters_uint = strtoul ((gchar*) num_raters, NULL, 10);
+			xmlFree (num_raters);
+
+			average = xmlGetProp (node, (xmlChar*) "average");
+			if (average == NULL)
+				average_double = 0;
+			else
+				average_double = g_ascii_strtod ((gchar*) average, NULL);
+			xmlFree (average);
+
+			self->priv->rating.min = strtoul ((gchar*) min, NULL, 10);
+			self->priv->rating.max = strtoul ((gchar*) max, NULL, 10);
+			self->priv->rating.count = num_raters_uint;
+			self->priv->rating.average = average_double;
+		} else if (xmlStrcmp (node->name, (xmlChar*) "comments") == 0) {
+			/* gd:comments */
+			xmlChar *rel, *href, *count_hint, *read_only;
+			xmlNode *child_node;
+			guint count_hint_uint;
+
+			/* This is actually the child of the <comments> element */
+			child_node = node->children;
+
+			count_hint = xmlGetProp (child_node, (xmlChar*) "countHint");
+			if (count_hint == NULL)
+				count_hint_uint = 0;
+			else
+				count_hint_uint = strtoul ((gchar*) count_hint, NULL, 10);
+			xmlFree (count_hint);
+
+			read_only = xmlGetProp (child_node, (xmlChar*) "readOnly");
+			rel = xmlGetProp (child_node, (xmlChar*) "rel");
+			href = xmlGetProp (child_node, (xmlChar*) "href");
+
+			/* TODO */
+			/*gdata_gd_feed_link_free (self->priv->comments_feed_link);
+			self->priv->comments_feed_link = gdata_gd_feed_link_new ((gchar*) href, (gchar*) rel, count_hint_uint,
+										 ((xmlStrcmp (read_only, (xmlChar*) "true") == 0) ? TRUE : FALSE));*/
+
+			xmlFree (rel);
+			xmlFree (href);
+			xmlFree (read_only);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_youtube_video_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else if (gdata_parser_is_namespace (node, "http://gdata.youtube.com/schemas/2007";) == TRUE) {
+		if (xmlStrcmp (node->name, (xmlChar*) "statistics") == 0) {
+			/* yt:statistics */
+			xmlChar *view_count, *favorite_count;
+
+			/* View count */
+			view_count = xmlGetProp (node, (xmlChar*) "viewCount");
+			if (view_count == NULL)
+				return gdata_parser_error_required_property_missing (node, "viewCount", error);
+			self->priv->view_count = strtoul ((gchar*) view_count, NULL, 10);
+			xmlFree (view_count);
+
+			/* Favourite count */
+			favorite_count = xmlGetProp (node, (xmlChar*) "favoriteCount");
+			self->priv->favorite_count = (favorite_count != NULL) ? strtoul ((gchar*) favorite_count, NULL, 10) : 0;
+			xmlFree (favorite_count);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "location") == 0) {
+			/* yt:location */
+			g_free (self->priv->location);
+			self->priv->location = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "noembed") == 0) {
+			/* yt:noembed */
+			gdata_youtube_video_set_no_embed (self, TRUE);
+		} else if (xmlStrcmp (node->name, (xmlChar*) "recorded") == 0) {
+			/* yt:recorded */
+			xmlChar *recorded;
+			GTimeVal recorded_timeval;
+
+			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 (node, (gchar*) recorded, error);
+				xmlFree (recorded);
+				return FALSE;
+			}
+			xmlFree (recorded);
+			gdata_youtube_video_set_recorded (self, &recorded_timeval);
+		} else {
+			return GDATA_PARSABLE_CLASS (gdata_youtube_video_parent_class)->parse_xml (parsable, doc, node, user_data, error);
+		}
+	} else {
+		return GDATA_PARSABLE_CLASS (gdata_youtube_video_parent_class)->parse_xml (parsable, doc, node, user_data, error);
 	}
 
 	return TRUE;
diff --git a/gdata/tests/picasaweb.c b/gdata/tests/picasaweb.c
index 9cec26d..4e8e1ad 100644
--- a/gdata/tests/picasaweb.c
+++ b/gdata/tests/picasaweb.c
@@ -777,7 +777,7 @@ test_photo_feed_entry (gconstpointer service)
 	g_assert_cmpuint (g_list_length (files), ==, 1);
 
 	g_assert_cmpstr (gdata_entry_get_title (photo_entry), ==, "100_0269.jpg");
-	g_assert_cmpstr (gdata_entry_get_id (photo_entry), ==, "5328890138794566386");
+	g_assert_cmpstr (gdata_entry_get_id (photo_entry), ==, "http://picasaweb.google.com/data/entry/user/libgdata.picasaweb/albumid/5328889949261497249/photoid/5328890138794566386";);
 	g_assert_cmpstr (gdata_entry_get_etag (photo_entry), !=, NULL);
 
 	gdata_entry_get_updated (photo_entry, &_time);
@@ -984,7 +984,7 @@ test_album_feed_entry (gconstpointer service)
 
 	/* Tests */
 	g_assert_cmpstr (gdata_entry_get_title (entry), ==, "Test Album 1 - Venice - Public");
-	g_assert_cmpstr (gdata_entry_get_id (entry), ==, "5328889949261497249");
+	g_assert_cmpstr (gdata_entry_get_id (entry), ==, "http://picasaweb.google.com/data/entry/user/libgdata.picasaweb/albumid/5328889949261497249";);
 	g_assert_cmpstr (gdata_entry_get_etag (entry), !=, NULL);
 	g_assert_cmpstr (gdata_entry_get_rights (entry), ==, "public");
 



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