private static FeedItem MakeFeedItem(XmlReader reader, DateTime defaultItemDate) { string description = null; string id = null; string parentId = null; string link = null; string title = null; string subject = null; string author = null; Enclosure enclosure = null; bool dirtyFlag = false; //int commentCount = NewsItem.NoComments; int commentCount = 0; DateTime date = defaultItemDate; DateTime now = date; Hashtable optionalElements = new Hashtable(); //Flagged flagged = Flagged.None; ArrayList subjects = new ArrayList(); string itemNamespaceUri = reader.NamespaceURI; //the namespace URI of the RSS item bool nodeRead = false; //indicates whether the last node was read using XmlDocument.ReadNode() while ((nodeRead || reader.Read()) && reader.NodeType != XmlNodeType.EndElement) { nodeRead = false; object localname = reader.LocalName; object namespaceuri = reader.NamespaceURI; if (reader.NodeType != XmlNodeType.Element) { continue; } /* string nodeNamespaceUri = reader.NamespaceURI; * if (StringHelper.EmptyOrNull(nodeNamespaceUri)) * nodeNamespaceUri = itemNamespaceUri; */ // if in node has no namespace, assume in RSS namespace // save some string comparisons bool nodeNamespaceUriEqual2Item = reader.NamespaceURI.Equals(itemNamespaceUri); bool nodeNamespaceUriEqual2DC = (namespaceuri == nameRefs[(int)NameTableIndexes.ns_dc]); if ((description == null) || (localname == nameRefs[(int)NameTableIndexes.body]) || (localname == nameRefs[(int)NameTableIndexes.encoded])) { //prefer to replace rss:description/dc:description with content:encoded if ((namespaceuri == nameRefs[(int)NameTableIndexes.ns_xhtml]) && (localname == nameRefs[(int)NameTableIndexes.body])) { if (!reader.IsEmptyElement) { XmlElement elem = (XmlElement)optionalElementsDoc.ReadNode(reader); nodeRead = true; description = elem.InnerXml; elem = null; } continue; } else if ((namespaceuri == nameRefs[(int)NameTableIndexes.ns_content]) && (localname == nameRefs[(int)NameTableIndexes.encoded])) { if (!reader.IsEmptyElement) { description = ReadElementString(reader); } continue; } else if ((nodeNamespaceUriEqual2Item || nodeNamespaceUriEqual2DC) && (localname == nameRefs[(int)NameTableIndexes.description])) { if (!reader.IsEmptyElement) { description = ReadElementString(reader); } continue; } } if (localname == nameRefs[(int)NameTableIndexes.enclosure]) { enclosure = new Enclosure(); enclosure.Url = FeedParser.ReadAttribute(reader, "url"); enclosure.Type = FeedParser.ReadAttribute(reader, "type"); enclosure.Length = Convert.ToInt32(FeedParser.ReadAttribute(reader, "length")); } if (link != null && link.Trim().Length == 0) { link = null; // reset on empty elements } if ((link == null) || (localname == nameRefs[(int)NameTableIndexes.guid])) { //favor rss:guid over rss:link if (nodeNamespaceUriEqual2Item && (localname == nameRefs[(int)NameTableIndexes.guid])) { if ((reader["isPermaLink"] == null) || (StringHelper.AreEqualCaseInsensitive(reader["isPermaLink"], "true"))) { if (!reader.IsEmptyElement) { link = ReadElementString(reader); } } else if (StringHelper.AreEqualCaseInsensitive(reader["isPermaLink"], "false")) { if (!reader.IsEmptyElement) { id = ReadElementString(reader); } } continue; } else if (nodeNamespaceUriEqual2Item && (localname == nameRefs[(int)NameTableIndexes.link])) { if (!reader.IsEmptyElement) { link = ReadElementString(reader); } continue; } } if (title == null) { if (nodeNamespaceUriEqual2Item && (localname == nameRefs[(int)NameTableIndexes.title])) { if (!reader.IsEmptyElement) { title = ReadElementString(reader); } continue; } } if (localname == nameRefs[(int)NameTableIndexes.dirtyFlag]) { if (!reader.IsEmptyElement) { dirtyFlag = Boolean.Parse(ReadElementString(reader)); } continue; } if ((author == null) || (localname == nameRefs[(int)NameTableIndexes.creator])) { //prefer dc:creator to <author> if (nodeNamespaceUriEqual2DC && (localname == nameRefs[(int)NameTableIndexes.creator] || localname == nameRefs[(int)NameTableIndexes.author])) { if (!reader.IsEmptyElement) { author = ReadElementString(reader); } continue; } else if (nodeNamespaceUriEqual2Item && (localname == nameRefs[(int)NameTableIndexes.author])) { if (!reader.IsEmptyElement) { author = ReadElementString(reader); } continue; } } if ((parentId == null) && (localname == nameRefs[(int)NameTableIndexes.reference])) { if (namespaceuri == nameRefs[(int)NameTableIndexes.ns_annotate]) { parentId = reader.GetAttribute("resource", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); } continue; } if (nodeNamespaceUriEqual2DC && (localname == nameRefs[(int)NameTableIndexes.subject])) { if (!reader.IsEmptyElement) { subjects.Add(ReadElementString(reader)); } continue; } else if (nodeNamespaceUriEqual2Item && (localname == nameRefs[(int)NameTableIndexes.category])) { if (!reader.IsEmptyElement) { subjects.Add(ReadElementString(reader)); } continue; } if (commentCount == 0) { if ((localname == nameRefs[(int)NameTableIndexes.comments]) && (namespaceuri == nameRefs[(int)NameTableIndexes.ns_slash])) { try { if (!reader.IsEmptyElement) { commentCount = Int32.Parse(ReadElementString(reader)); } } catch (Exception) { /* DO NOTHING */ } continue; } } if (date == now) { try { if (nodeNamespaceUriEqual2Item && (localname == nameRefs[(int)NameTableIndexes.pubdate])) { if (!reader.IsEmptyElement) { date = DateTimeExt.Parse(ReadElementString(reader)); } continue; } else if (nodeNamespaceUriEqual2DC && (localname == nameRefs[(int)NameTableIndexes.date])) { if (!reader.IsEmptyElement) { date = DateTimeExt.ToDateTime(ReadElementString(reader)); } continue; } } catch (FormatException fe) { System.Diagnostics.Debug.WriteLine(fe.ToString()); /* date was improperly formated*/ //_log.Warn("Error parsing date from item {" + subject + // "} from feed {" + link + "}: " + fe.Message); continue; } } XmlQualifiedName qname = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI); XmlNode optionalNode = optionalElementsDoc.ReadNode(reader); nodeRead = true; /* some elements occur multiple times in feeds, only the 1st is picked */ if (!optionalElements.Contains(qname)) { optionalElements.Add(qname, optionalNode); } } //while //HACK: Sometimes we get garbled items due to network issues, this ensures we don't send them to the UI if (link == null && id == null && title == null && date == now) { return(null); } /* create Subject if any */ for (int i = 0; i < subjects.Count; i++) { subject += (i > 0 ? " | " + subjects[i] : subjects[i]); } /* set value of id to link if no guid in XML stream */ id = (id == null ? link : id); FeedItem newsItem = new FeedItem(); //f, title, link, description, date, subject, ctype, optionalElements, id, parentId); newsItem.Title = title; newsItem.Id = id; newsItem.Link = link; newsItem.Description = description; newsItem.PubDate = date; newsItem.Enclosure = enclosure; newsItem.OptionalElements = optionalElements; newsItem.CommentCount = commentCount; newsItem.Author = author; newsItem.DirtyFlag = dirtyFlag; return(newsItem); }
/// <summary> /// Initializes a new instance of the FeedSerializer. /// </summary> public FeedSerializer() { parser = new FeedParser(); }