how do i consume extended syndicated content

Topics: Argotic.Extensions, Request For Comments (RFC)
Aug 27, 2008 at 12:10 AM
Edited Aug 27, 2008 at 12:15 AM
I have created a custom SyndicationExtension for custom items of an rss feed i'm trying to parse, and use the following below to try and get the custom nodes in the item nodes


foreach (RssItem item in this._feedInfo.Feed.Channel.Items)
            {
                if (item.HasExtensions)
                {
                    MyCustomExtension customExt = item.FindExtension(MyCustomExtension.MatchByType) as MyCustomExtension;
                    if (customExt != null)
                    {
                        Console.WriteLine(customExt.CustomField);
                    }
                }
                break;
            }


But it doesn't seem to be finding this custom extension when it parses the item,

i have tried this also when loading the feed

SyndicationResourceLoadSettings extSettings = new SyndicationResourceLoadSettings();
extSettings.SupportedExtensions.Add(typeof(MyCustomExtension));
getConditionalFeedInfo.Feed.Load(reader, extensionSettings);


Any ideas or help would be greatly appreciated

I can't find any examples or documentation of how to load these custom extensions

here is an example of my feed

<item>
    <title>titleHEre</title>
    <foo:CustomField>foobar</foo:CustomField>
</item>
Coordinator
Aug 27, 2008 at 3:31 AM
If you could send me the code for your custom extension along with a sample feed, I should be able to pinpoint the problem. What you are doing is correct in that you are adding the custom extension using the load settings and using a predicate based look-up on the feed. I would suggest enumerating the extensions collection to see if your extension exists.
Aug 27, 2008 at 3:06 PM
how do i enumerate the the extensions, any examples of that anywhere
Coordinator
Aug 27, 2008 at 4:01 PM
All syndication entities that are extensible implement the IExtensibleSyndicationObject interface, which provides the following properties:
  • public IEnumerable<ISyndicationExtension> Extensions
  • public bool HasExtensions

You can enumerate extensions using the Extensions property.

Aug 27, 2008 at 6:01 PM
it appears to be loading the extension, here is the feed i'm trying to handle, http://www.whiskeymilitia.com/docs/wm/rssplus.xml  its the odat elements under the item node, that i can't seem to parse

here is my extension

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;

using Argotic.Common;
using Argotic.Extensions;

namespace Foo.Foobar
{
    /// <summary>
    /// Provides a simple example of a custom syndication extension.
    /// </summary>
    public class ODATSyndicationExtension : SyndicationExtension, IComparable
    {
        //============================================================
        //    PUBLIC/PRIVATE/PROTECTED MEMBERS
        //============================================================
        #region PRIVATE/PROTECTED/PUBLIC MEMBERS
        /// <summary>
        /// Private member to hold the value of the custom syndication extension's attribute.
        /// </summary>
        private string _brand = String.Empty;
        #endregion

        //============================================================
        //    CONSTRUCTORS
        //============================================================
        #region ODATSyndicationExtension()
        /// <summary>
        /// Initializes a new instance of the <see cref="ODATSyndicationExtension"/> class.
        /// </summary>
        public ODATSyndicationExtension()
            : base("odat", "http://www.whiskeymilitia.com/docs/wm/rssplus.xml", new Version("1.0"), new Uri("http://www.example.com/spec"), "odat", "ODAT syndication extension")
        {
            // Class state initialized by abstract SyndicationExtension base class
        }
        #endregion

        //============================================================
        //    PUBLIC PROPERTIES
        //============================================================
        #region MyAttribute
        /// <summary>
        /// Gets or sets the value of the extension attribute.
        /// </summary>
        /// <value>The value of the extension attribute.</value>
        public string Brand
        {
            get
            {
                return _brand;
            }

            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    _brand = String.Empty;
                }
                else
                {
                    _brand = value.Trim();
                }
            }
        }
        #endregion

        //============================================================
        //    STATIC METHODS
        //============================================================
        #region MatchByType(ISyndicationExtension extension)
        /// <summary>
        /// Predicate delegate that returns a value indicating if the supplied <see cref="ISyndicationExtension"/>
        /// represents the same <see cref="Type"/> as this <see cref="ODATSyndicationExtension"/>.
        /// </summary>
        /// <param name="extension">The <see cref="ISyndicationExtension"/> to be compared.</param>
        /// <returns><b>true</b> if the <paramref name="extension"/> is the same <see cref="Type"/> as this <see cref="ODATSyndicationExtension"/>; otherwise, <b>false</b>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="extension"/> is a null reference (Nothing in Visual Basic).</exception>
        public static bool MatchByType(ISyndicationExtension extension)
        {
            Guard.ArgumentNotNull(extension, "extension");

            //------------------------------------------------------------
            //    Determine if search condition was met
            //------------------------------------------------------------
            if (extension.GetType() == typeof(ODATSyndicationExtension))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        //============================================================
        //    PUBLIC METHODS
        //============================================================
        #region Load(IXPathNavigable source)
        /// <summary>
        /// Initializes the syndication extension using the supplied <see cref="IXPathNavigable"/>.
        /// </summary>
        /// <param name="source">The <b>IXPathNavigable</b> used to load this <see cref="ODATSyndicationExtension"/>.</param>
        /// <returns><b>true</b> if the <see cref="ODATSyndicationExtension"/> was able to be initialized using the supplied <paramref name="source"/>; otherwise <b>false</b>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="source"/> is a null reference (Nothing in Visual Basic).</exception>
        public override bool Load(IXPathNavigable source)
        {
            //------------------------------------------------------------
            //    Local members
            //------------------------------------------------------------
            bool wasLoaded = false;

            //------------------------------------------------------------
            //    Validate parameter
            //------------------------------------------------------------
            Guard.ArgumentNotNull(source, "source");

            //------------------------------------------------------------
            //    Attempt to extract syndication extension information
            //------------------------------------------------------------
            XPathNavigator navigator = source.CreateNavigator();
            if (navigator.HasAttributes)
            {
                string brand = navigator.GetAttribute("Brand", String.Empty);
                if (!String.IsNullOrEmpty(brand))
                {
                    this.Brand = brand;
                    wasLoaded = true;
                }
            }

            //------------------------------------------------------------
            //    Raise extension loaded event
            //------------------------------------------------------------
            SyndicationExtensionLoadedEventArgs args = new SyndicationExtensionLoadedEventArgs(source, this);
            this.OnExtensionLoaded(args);

            return wasLoaded;
        }
        #endregion

        #region Load(XmlReader reader)
        /// <summary>
        /// Initializes the syndication extension using the supplied <see cref="XmlReader"/>.
        /// </summary>
        /// <param name="reader">The <b>XmlReader</b> used to load this <see cref="ODATSyndicationExtension"/>.</param>
        /// <returns><b>true</b> if the <see cref="ODATSyndicationExtension"/> was able to be initialized using the supplied <paramref name="reader"/>; otherwise <b>false</b>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="reader"/> is a null reference (Nothing in Visual Basic).</exception>
        public override bool Load(XmlReader reader)
        {
            //------------------------------------------------------------
            //    Validate parameter
            //------------------------------------------------------------
            Guard.ArgumentNotNull(reader, "reader");

            //------------------------------------------------------------
            //    Create navigator against reader and pass to load method
            //------------------------------------------------------------
            XPathDocument document = new XPathDocument(reader);

            return this.Load(document.CreateNavigator());
        }
        #endregion

        #region WriteTo(XmlWriter writer)
        /// <summary>
        /// Writes the syndication extension to the specified <see cref="XmlWriter"/>.
        /// </summary>
        /// <param name="writer">The <b>XmlWriter</b> to which you want to write the syndication extension.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="writer"/> is a null reference (Nothing in Visual Basic).</exception>
        public override void WriteTo(XmlWriter writer)
        {
            //------------------------------------------------------------
            //    Validate parameter
            //------------------------------------------------------------
            Guard.ArgumentNotNull(writer, "writer");

            //------------------------------------------------------------
            //    Write current extension details to the writer
            //------------------------------------------------------------
            writer.WriteStartElement("odatExtension", this.XmlNamespace);

            if (!String.IsNullOrEmpty(this.Brand))
            {
                writer.WriteAttributeString("Brand", this.Brand);
            }

            writer.WriteEndElement();
        }
        #endregion

        //============================================================
        //    PUBLIC OVERRIDES
        //============================================================
        #region ToString()
        /// <summary>
        /// Returns a <see cref="String"/> that represents the current <see cref="ODATSyndicationExtension"/>.
        /// </summary>
        /// <returns>A <see cref="String"/> that represents the current <see cref="ODATSyndicationExtension"/>.</returns>
        /// <remarks>
        ///     This method returns the XML representation for the current instance.
        /// </remarks>
        public override string ToString()
        {
            //------------------------------------------------------------
            //    Build the string representation
            //------------------------------------------------------------
            using (MemoryStream stream = new MemoryStream())
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                settings.Indent = true;
                settings.OmitXmlDeclaration = true;

                using (XmlWriter writer = XmlWriter.Create(stream, settings))
                {
                    this.WriteTo(writer);
                }

                stream.Seek(0, SeekOrigin.Begin);

                using (StreamReader reader = new StreamReader(stream))
                {
                    return reader.ReadToEnd();
                }
            }
        }
        #endregion

        //============================================================
        //    ICOMPARABLE IMPLEMENTATION
        //============================================================
        #region CompareTo(object obj)
        /// <summary>
        /// Compares the current instance with another object of the same type.
        /// </summary>
        /// <param name="obj">An object to compare with this instance.</param>
        /// <returns>A 32-bit signed integer that indicates the relative order of the objects being compared.</returns>
        /// <exception cref="ArgumentException">The <paramref name="obj"/> is not the expected <see cref="Type"/>.</exception>
        public int CompareTo(object obj)
        {
            //------------------------------------------------------------
            //    If target is a null reference, instance is greater
            //------------------------------------------------------------
            if (obj == null)
            {
                return 1;
            }

            //------------------------------------------------------------
            //    Determine comparison result using property state of objects
            //------------------------------------------------------------
            ODATSyndicationExtension value = obj as ODATSyndicationExtension;

            if (value != null)
            {
                // Base class properties
                int result = String.Compare(this.Description, value.Description, StringComparison.OrdinalIgnoreCase);
                result = result | Uri.Compare(this.Documentation, value.Documentation, UriComponents.AbsoluteUri, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase);
                result = result | String.Compare(this.Name, value.Name, StringComparison.OrdinalIgnoreCase);
                result = result | this.Version.CompareTo(value.Version);
                result = result | String.Compare(this.XmlNamespace, value.XmlNamespace, StringComparison.Ordinal);
                result = result | String.Compare(this.XmlPrefix, value.XmlPrefix, StringComparison.Ordinal);

                // Custom extension properties
                result = result | String.Compare(this.Brand, value.Brand, StringComparison.OrdinalIgnoreCase);

                return result;
            }
            else
            {
                throw new ArgumentException(String.Format(null, "obj is not of type {0}, type was found to be '{1}'.", this.GetType().FullName, obj.GetType().FullName), "obj");
            }
        }
        #endregion

        #region Equals(Object obj)
        /// <summary>
        /// Determines whether the specified <see cref="Object"/> is equal to the current instance.
        /// </summary>
        /// <param name="obj">The <see cref="Object"/> to compare with the current instance.</param>
        /// <returns><b>true</b> if the specified <see cref="Object"/> is equal to the current instance; otherwise, <b>false</b>.</returns>
        public override bool Equals(Object obj)
        {
            //------------------------------------------------------------
            //    Determine equality via type then by comparision
            //------------------------------------------------------------
            if (!(obj is ODATSyndicationExtension))
            {
                return false;
            }

            return (this.CompareTo(obj) == 0);
        }
        #endregion

        #region GetHashCode()
        /// <summary>
        /// Returns a hash code for the current instance.
        /// </summary>
        /// <returns>A 32-bit signed integer hash code.</returns>
        public override int GetHashCode()
        {
            //------------------------------------------------------------
            //    Generate has code using unique value of ToString() method
            //------------------------------------------------------------
            char[] charArray = this.ToString().ToCharArray();

            return charArray.GetHashCode();
        }
        #endregion

        #region == operator
        /// <summary>
        /// Determines if operands are equal.
        /// </summary>
        /// <param name="first">Operand to be compared.</param>
        /// <param name="second">Operand to compare to.</param>
        /// <returns><b>true</b> if the values of its operands are equal, otherwise; <b>false</b>.</returns>
        public static bool operator ==(ODATSyndicationExtension first, ODATSyndicationExtension second)
        {
            //------------------------------------------------------------
            //    Handle null reference comparison
            //------------------------------------------------------------
            if (object.Equals(first, null) && object.Equals(second, null))
            {
                return true;
            }
            else if (object.Equals(first, null) && !object.Equals(second, null))
            {
                return false;
            }

            return first.Equals(second);
        }
        #endregion

        #region != operator
        /// <summary>
        /// Determines if operands are not equal.
        /// </summary>
        /// <param name="first">Operand to be compared.</param>
        /// <param name="second">Operand to compare to.</param>
        /// <returns><b>false</b> if its operands are equal, otherwise; <b>true</b>.</returns>
        public static bool operator !=(ODATSyndicationExtension first, ODATSyndicationExtension second)
        {
            return !(first == second);
        }
        #endregion

        #region < operator
        /// <summary>
        /// Determines if first operand is less than second operand.
        /// </summary>
        /// <param name="first">Operand to be compared.</param>
        /// <param name="second">Operand to compare to.</param>
        /// <returns><b>true</b> if the first operand is less than the second, otherwise; <b>false</b>.</returns>
        public static bool operator <(ODATSyndicationExtension first, ODATSyndicationExtension second)
        {
            //------------------------------------------------------------
            //    Handle null reference comparison
            //------------------------------------------------------------
            if (object.Equals(first, null) && object.Equals(second, null))
            {
                return false;
            }
            else if (object.Equals(first, null) && !object.Equals(second, null))
            {
                return true;
            }

            return (first.CompareTo(second) < 0);
        }
        #endregion

        #region > operator
        /// <summary>
        /// Determines if first operand is greater than second operand.
        /// </summary>
        /// <param name="first">Operand to be compared.</param>
        /// <param name="second">Operand to compare to.</param>
        /// <returns><b>true</b> if the first operand is greater than the second, otherwise; <b>false</b>.</returns>
        public static bool operator >(ODATSyndicationExtension first, ODATSyndicationExtension second)
        {
            //------------------------------------------------------------
            //    Handle null reference comparison
            //------------------------------------------------------------
            if (object.Equals(first, null) && object.Equals(second, null))
            {
                return false;
            }
            else if (object.Equals(first, null) && !object.Equals(second, null))
            {
                return false;
            }

            return (first.CompareTo(second) > 0);
        }
        #endregion
    }
}

Aug 27, 2008 at 6:02 PM
when it gets to this part,

XPathNavigator navigator = source.CreateNavigator();
            if (navigator.HasAttributes)
            {
                string brand = navigator.GetAttribute("Brand", String.Empty);
                if (!String.IsNullOrEmpty(brand))
                {
                    this.Brand = brand;
                    wasLoaded = true;
                }
            }

it never has any attributes
Coordinator
Aug 28, 2008 at 7:32 PM
You might want to verify that the extension XML namespace has been added to the XmlNamespaceManager used when parsing the source XML data.
Either way, fire me your code and I will try to take the time to look it over and figure out the problem.
- Brian Kuhn

On 27 Aug 2008 11:02:34 -0700, slim7 <notifications@codeplex.com> wrote:

From: slim7

when it gets to this part,

XPathNavigator navigator = source.CreateNavigator();
if (navigator.HasAttributes)
{
string brand = navigator.GetAttribute("Brand", String.Empty);
if (!String.IsNullOrEmpty(brand))
{
this.Brand = brand;
wasLoaded = true;
}
}

it never has any attributes

Read the full discussion online.

To add a post to this discussion, reply to this email (Argotic@discussions.codeplex.com)

To start a new discussion for this project, email Argotic@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Sep 2, 2008 at 6:14 PM
Here is a test i'm running to test my extension, and i attached my Extension file, also where would i check that XmlNamespaceManager ? ?

thanks again, let me know anything you find,

[Test]
public void TestODATExtension()
{

string url = "http://www.whiskeymilitia.com/docs/wm/rssplus.xml";
Uri source = new Uri(url);
DateTime lastModified;
string entityTag;

////------------------------------------------------------------
//// Retrieve the modification date and entity tag information
////------------------------------------------------------------
HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(source);
httpRequest.AllowAutoRedirect = true;
httpRequest.KeepAlive = true;
httpRequest.UserAgent = "Some User Agent 1.0.0.0";

HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();

lastModified = httpResponse.LastModified;
entityTag = httpResponse.Headers[HttpResponseHeader.ETag];

///*
// Typically the consumer would store the modification date and entity tag information for the resource,
// and some amount of time passes. Consumer can now use a conditional GET operation to determine if
// the web resource has changed since it was last retrieved. This minimizes bandwidth usage significantly.
//*/

//------------------------------------------------------------
// Determine if web resource has been modified
//------------------------------------------------------------
//WebResponse conditionalResponse = SyndicationDiscoveryUtility.ConditionalGet(source, lastModified, entityTag);
//if (conditionalResponse != null)
//{
// // Web resource has been modified since last retrieval, consumer would process the new data.
//}

StreamReader rssStream = new StreamReader(httpResponse.GetResponseStream(), Encoding.ASCII);

XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreWhitespace = true;
RssFeed feed = new RssFeed();

using (XmlReader reader = XmlReader.Create(rssStream, settings))
{
SyndicationResourceLoadSettings extSettings = new SyndicationResourceLoadSettings();
extSettings.SupportedExtensions.Add(typeof(ODATSyndicationExtension));
feed.Load(reader, extSettings);
}

foreach (RssItem item in feed.Channel.Items)
{
Assert.IsTrue(item.HasExtensions);
}

}

On Thu, Aug 28, 2008 at 1:32 PM, Oppositional <notifications@codeplex.com> wrote:

From: Oppositional

You might want to verify that the extension XML namespace has been added to the XmlNamespaceManager used when parsing the source XML data.
Either way, fire me your code and I will try to take the time to look it over and figure out the problem.
- Brian Kuhn

On 27 Aug 2008 11:02:34 -0700, slim7 <notifications@codeplex.com> wrote:

From: slim7

when it gets to this part,

XPathNavigator navigator = source.CreateNavigator();
if (navigator.HasAttributes)
{
string brand = navigator.GetAttribute("Brand", String.Empty);
if (!String.IsNullOrEmpty(brand))
{
this.Brand = brand;
wasLoaded = true;
}
}

it never has any attributes

Read the full discussion online.

To add a post to this discussion, reply to this email (Argotic@discussions.codeplex.com)

To start a new discussion for this project, email Argotic@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Read the full discussion online.

To add a post to this discussion, reply to this email (Argotic@discussions.codeplex.com)

To start a new discussion for this project, email Argotic@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Sep 4, 2008 at 3:54 PM
did you get the attachment on that last post ??
Coordinator
Sep 5, 2008 at 2:43 AM
No, I did not. Please email your code to oppositional@live.com and I'll try to get to it as soon as possible, but I am currently swamped at work.