void xml_reader_move_up_to_depth (XmlReader *reader, gint depth) { g_return_if_fail(XML_IS_READER(reader)); while (xml_reader_get_depth(reader) > depth) xml_reader_read_end_element(reader); }
static gboolean news_format_rss_read_from_xml (NewsFormatRss *rss, XmlReader *reader, NewsFeed *feed, GError **error) { GHashTable *categories = NULL; GHashTable *persons = NULL; GHashTable *links = NULL; GomAdapter *adapter; gchar *str; ENTRY; g_return_val_if_fail(NEWS_IS_FORMAT_RSS(rss), FALSE); g_return_val_if_fail(XML_IS_READER(reader), FALSE); g_return_val_if_fail(NEWS_IS_FEED(feed), FALSE); adapter = news_format_get_adapter(NEWS_FORMAT(rss)); g_assert(adapter); skip: if (!xml_reader_read_to_next(reader) || !xml_reader_is_a(reader, "rss")) { if (xml_reader_is_a(reader, "xml-stylesheet") || xml_reader_is_a(reader, "#comment")) { goto skip; } RETURN_ERROR; } if (!xml_reader_is_a_local(reader, "rss")) { RETURN_ERROR; } if ((str = xml_reader_get_attribute(reader, "version"))) { if (!!g_strcmp0(str, "2.0")) { g_set_error(error, XML_READER_ERROR, XML_READER_ERROR_INVALID, _("RSS Version \"%s\" is not supported."), str); g_free(str); RETURN(FALSE); } g_free(str); } if (!xml_reader_read_start_element(reader, "channel")) { RETURN_ERROR; } persons = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); categories = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); links = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); xml_reader_read(reader); for (xml_reader_read_to_next(reader); xml_reader_get_node_type(reader) != XML_READER_TYPE_END_ELEMENT; xml_reader_read_to_next(reader)) { if ((xml_reader_get_node_type(reader) != XML_READER_TYPE_ELEMENT) || rss->priv->error) { g_hash_table_destroy(categories); g_hash_table_destroy(persons); g_hash_table_destroy(links); RETURN_ERROR; } if (xml_reader_is_a_local(reader, "title")) { str = xml_reader_read_string(reader); g_object_set(feed, "title", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "link")) { GomCollection *collection; NewsLink *link_; g_object_get(feed, "links", &collection, NULL); if ((link_ = news_format_rss_read_link(rss, reader, links))) { gom_collection_add_resource(collection, GOM_RESOURCE(link_)); g_object_unref(link_); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "description")) { str = xml_reader_read_string(reader); g_object_set(feed, "description", str, NULL); g_free(str); xml_reader_read_end_element(reader); } else if (xml_reader_is_a_local(reader, "language")) { str = xml_reader_read_string(reader); g_object_set(feed, "language", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "copyright")) { str = xml_reader_read_string(reader); g_object_set(feed, "copyright", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "managingEditor")) { GomCollection *collection; NewsPerson *person; g_object_get(feed, "authors", &collection, NULL); if ((person = news_format_rss_read_person(rss, reader, persons))) { gom_collection_add_resource(collection, GOM_RESOURCE(person)); g_object_unref(person); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "pubDate") || xml_reader_is_a_local(reader, "lastBuildDate")) { GDateTime *dt; GTimeVal tv; if ((str = xml_reader_read_string(reader))) { if (g_time_val_from_iso8601(str, &tv)) { if ((dt = g_date_time_new_from_timeval_utc(&tv))) { g_object_set(feed, "last-updated-at", dt, NULL); g_date_time_unref(dt); } } g_free(str); } } else if (xml_reader_is_a_local(reader, "category")) { GomCollection *collection; NewsCategory *category; g_object_get(feed, "categories", &collection, NULL); if ((category = news_format_rss_read_category(rss, reader, categories))) { gom_collection_add_resource(collection, GOM_RESOURCE(category)); g_object_unref(category); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "generator")) { str = xml_reader_read_string(reader); g_object_set(feed, "generator", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "item")) { GomCollection *collection; NewsItem *item; g_object_get(feed, "items", &collection, NULL); item = g_object_new(NEWS_TYPE_ITEM, "adapter", adapter, "is-new", TRUE, NULL); if (news_format_rss_read_item(rss, reader, item, persons, categories, links)) { gom_collection_add_resource(collection, GOM_RESOURCE(item)); } g_object_unref(item); g_object_unref(collection); } } g_hash_table_destroy(categories); g_hash_table_destroy(links); g_hash_table_destroy(persons); RETURN(TRUE); }
static gboolean news_format_rss_read_item (NewsFormatRss *rss, XmlReader *reader, NewsItem *item, GHashTable *persons, GHashTable *categories, GHashTable *links) { gchar *str; xml_reader_read(reader); for (; xml_reader_get_node_type(reader) != XML_READER_TYPE_END_ELEMENT; xml_reader_read_to_next(reader)) { if (rss->priv->error) { break; } if (xml_reader_is_a_local(reader, "author")) { GomCollection *collection; NewsPerson *person; g_object_get(item, "authors", &collection, NULL); if ((person = news_format_rss_read_person(rss, reader, persons))) { gom_collection_add_resource(collection, GOM_RESOURCE(person)); g_object_unref(person); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "category")) { GomCollection *collection; NewsCategory *category; g_object_get(item, "categories", &collection, NULL); if ((category = news_format_rss_read_category(rss, reader, categories))) { gom_collection_add_resource(collection, GOM_RESOURCE(category)); g_object_unref(category); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "link")) { GomCollection *collection; NewsLink *link_; g_object_get(item, "links", &collection, NULL); if ((link_ = news_format_rss_read_link(rss, reader, links))) { gom_collection_add_resource(collection, GOM_RESOURCE(link_)); g_object_unref(link_); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "guid")) { str = xml_reader_read_string(reader); g_object_set(item, "item-id", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "description")) { str = xml_reader_read_inner_xml(reader); g_object_set(item, "summary", str, NULL); g_free(str); xml_reader_read_end_element(reader); } else if (xml_reader_is_a_local(reader, "title")) { str = xml_reader_read_string(reader); g_object_set(item, "title", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "pubDate")) { GDateTime *dt; GTimeVal tv; if ((str = xml_reader_read_string(reader))) { if (g_time_val_from_iso8601(str, &tv)) { if ((dt = g_date_time_new_from_timeval_utc(&tv))) { g_object_set(item, "last-updated-at", dt, NULL); g_date_time_unref(dt); } } g_free(str); } } else if (xml_reader_is_a_local(reader, "source")) { /* * TODO: */ } } xml_reader_read_end_element(reader); return TRUE; }