Пример #1
0
        private void ProcessHead(Opml opml, XmlNode headNode)
        {
            foreach (XmlNode node in headNode.ChildNodes)
            {
                string text = node.LocalName;
                text = string.IsInterned(text);

                if (text == "title")
                {
                    opml.Title = node.InnerText;
                }
                else if (text == "dateCreated")
                {
                    opml.DateCreated = DateTimeExt.Parse(node.InnerText);
                }
                else if (text == "dateModified")
                {
                    opml.DateModified = DateTimeExt.Parse(node.InnerText);
                }
                else if (text == "ownerEmail")
                {
                    opml.OwnerEmail = node.InnerText;
                }
                else if (text == "ownerName")
                {
                    opml.OwnerName = node.InnerText;
                }
            }
        }
Пример #2
0
        private static void ProcessFeedElements(Feed feed, XmlReader reader, string rssNamespaceUri, SyndicationFormat format, Hashtable optionalElements, ArrayList items, DateTime defaultItemDate)
        {
            bool matched  = false;            //indicates whether this is a known element
            bool nodeRead = false;            //indicates whether the last node was read using XmlDocument.ReadNode()

            //string feedTitle = "";
            //string feedDescription = "";
            //string feedLink = "";

            DateTime channelBuildDate = DateTime.MinValue;

            if ((format == SyndicationFormat.Rdf) || (format == SyndicationFormat.Rss))
            {
                while ((nodeRead || reader.Read()) && reader.NodeType != XmlNodeType.EndElement)
                {
                    object localname    = reader.LocalName;
                    object namespaceuri = reader.NamespaceURI;
                    matched  = false;
                    nodeRead = false;

                    if (reader.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }

                    if (reader.NamespaceURI.Equals(rssNamespaceUri) || reader.NamespaceURI.Equals(String.Empty))
                    {
                        if (localname == nameRefs[(int)NameTableIndexes.title])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                feed.Title = ReadElementString(reader);
                            }
                            matched = true;
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.description])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                feed.Description = ReadElementString(reader);
                            }
                            matched = true;
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.link])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                feed.Link = ReadElementString(reader);
                            }
                            matched = true;
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.lastbuilddate])
                        {
                            try
                            {
                                if (!reader.IsEmptyElement)
                                {
                                    feed.LastBuildDate = DateTimeExt.Parse(ReadElementString(reader));
                                }
                            }
                            catch (FormatException fex)
                            {
                                System.Diagnostics.Debug.WriteLine(fex.ToString());
                                //_log.Warn("Error parsing date from channel {" + feedTitle +
                                //    "} from feed {" + (feedLink == null ? f.title : feedLink) + "}: ", fex);
                            }
                            finally
                            {
                                matched = true;
                            }
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.items])
                        {
                            reader.Skip();
                            matched = true;
                        }
                        else if ((localname == nameRefs[(int)NameTableIndexes.image]) && format == SyndicationFormat.Rdf)
                        {
                            reader.Skip();
                            matched = true;
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.item])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                FeedItem rssItem = MakeFeedItem(reader, defaultItemDate);
                                if (rssItem != null)
                                {
                                    rssItem.Parent = feed;
                                    //items.Add(rssItem);
                                    feed.Items.Add(rssItem);
                                }
                            }
                            matched = true;
                        }
                    }
                    else if (namespaceuri == nameRefs[(int)NameTableIndexes.ns_bandit_2003])
                    {
                        if (localname == nameRefs[(int)NameTableIndexes.maxitemage])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                // get the old v1.2 value from cached feed
                                // We used the TimeSpan.Parse() / maxItemAge.ToString() there, so we cannot simply take over the string.
                                // Instead we convert to TimeSpan, then convert to valid xs:duration datatype to proceed correctly
                                //f.maxitemage = XmlConvert.ToString(TimeSpan.Parse(ReadElementString(reader)));
                                //f.maxitemage = ReadElementString(reader);
                            }
                            matched = true;
                        }
                    }

                    if (!matched)
                    {
                        XmlQualifiedName qname        = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI);
                        XmlNode          optionalNode = optionalElementsDoc.ReadNode(reader);

                        if (!optionalElements.Contains(qname))
                        {
                            optionalElements.Add(qname, optionalNode);
                        }

                        nodeRead = true;
                    }            //if(!matched)
                }                //while


                if (format == SyndicationFormat.Rdf)
                {
                    reader.ReadEndElement();                     //move to <image> or first <item>.

                    do
                    {
                        object localname = reader.LocalName;
                        nodeRead = false;

                        if ((localname == nameRefs[(int)NameTableIndexes.image]) &&
                            reader.NamespaceURI.Equals(rssNamespaceUri))
                        {                                                                   //RSS 1.0 can have <image> outside <channel>
                            XmlNode optionalNode = optionalElementsDoc.ReadNode(reader);
                            ((XmlElement)optionalNode).SetAttribute("xmlns", String.Empty); //change namespace decl to no namespace

                            XmlQualifiedName qname = new XmlQualifiedName(optionalNode.LocalName, optionalNode.NamespaceURI);

                            if (!optionalElements.Contains(qname))
                            {
                                optionalElements.Add(qname, optionalNode);
                            }

                            nodeRead = true;
                        }

                        if ((localname == nameRefs[(int)NameTableIndexes.item]) &&
                            reader.NamespaceURI.Equals(rssNamespaceUri))
                        {
                            if (!reader.IsEmptyElement)
                            {
                                FeedItem rssItem = MakeFeedItem(reader, defaultItemDate);
                                if (rssItem != null)
                                {
                                    items.Add(rssItem);
                                }
                            }
                        }
                    } while (nodeRead || reader.Read());
                }                // if(format == SyndicationFormat.Rdf)
            }
            else if (format == SyndicationFormat.Atom)
            {
                while ((nodeRead || reader.Read()) && reader.NodeType != XmlNodeType.EndElement)
                {
                    object localname    = reader.LocalName;
                    object namespaceuri = reader.NamespaceURI;
                    matched  = false;
                    nodeRead = false;

                    if (reader.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }


                    if (reader.NamespaceURI.Equals(rssNamespaceUri) || reader.NamespaceURI.Equals(String.Empty))
                    {
                        if (localname == nameRefs[(int)NameTableIndexes.title])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                feed.Title = ReadElementString(reader);
                            }
                            matched = true;
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.tagline])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                feed.Description = ReadElementString(reader);
                            }
                            matched = true;
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.link])
                        {
                            string rel  = reader.GetAttribute("rel");
                            string href = reader.GetAttribute("href");

                            if (feed.Link == String.Empty)
                            {
                                if ((rel != null) && (href != null) &&
                                    rel.Equals("alternate"))
                                {
                                    feed.Link = href;
                                    matched   = true;
                                }
                            }
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.modified])
                        {
                            try
                            {
                                if (!reader.IsEmptyElement)
                                {
                                    feed.LastBuildDate = DateTimeExt.Parse(ReadElementString(reader));
                                }
                            }
                            catch (FormatException fex)
                            {
                                System.Diagnostics.Debug.WriteLine(fex.ToString());
                                //_log.Warn("Error parsing date from channel {" + feedTitle +
                                //	"} from feed {" + (feedLink == null ? f.title : feedLink) + "}: ", fex);
                            }
                            finally
                            {
                                matched = true;
                            }
                        }
                        else if (localname == nameRefs[(int)NameTableIndexes.entry])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                FeedItem rssItem = MakeFeedItem(reader, defaultItemDate);
                                if (rssItem != null)
                                {
                                    items.Add(rssItem);
                                }
                            }
                            matched = true;
                        }
                    }
                    else if (namespaceuri == nameRefs[(int)NameTableIndexes.ns_bandit_2003])
                    {
                        if (localname == nameRefs[(int)NameTableIndexes.maxitemage])
                        {
                            if (!reader.IsEmptyElement)
                            {
                                // get the old v1.2 value from cached feed
                                // We used the TimeSpan.Parse() / maxItemAge.ToString() there, so we cannot simply take over the string.
                                // Instead we convert to TimeSpan, then convert to valid xs:duration datatype to proceed correctly
                                TimeSpan maxItemAgeTS = TimeSpan.Parse(ReadElementString(reader));

                                if (maxItemAgeTS != TimeSpan.MaxValue)
                                {
                                    //f.maxitemage = XmlConvert.ToString(maxItemAgeTS);
                                }
                            }
                            matched = true;
                        }
                    }

                    if (!matched)
                    {
                        XmlQualifiedName qname        = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI);
                        XmlNode          optionalNode = optionalElementsDoc.ReadNode(reader);

                        if (!optionalElements.Contains(qname))
                        {
                            optionalElements.Add(qname, optionalNode);
                        }

                        nodeRead = true;
                    }            //if(!matched)
                }                //while
            }
        }
Пример #3
0
        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);
        }