2

I've figured out how to append nodes to my rss document in the right structyre. I now need to sort it in the pubDate order and then output to screen. Looking at the examples online, I've found lots of XDocument and Linq stuff but nothing with XmlDocument. Scratching my head whether to scrap what code I have and work out how to do it in XDocument with advice from here or continue with XMLDocument and figure out a way to sort.

With XMLDocument I've got the code working exactly as I want, just need my feed to be sorted in pubDate order when it spits it out to the screen. So I think I will stick with this for the timebeing. I've found this article http://support.microsoft.com/kb/555060 and an xslt someone posted in Stack Overflow, but I dont know how to call the "XmlHelperFunctions" from my code. Is XSLT the easiest option I have, or is there something easier out there?

This is my code:

    XmlDocument xmlDoc = new XmlDocument();

    xmlDoc.LoadXml(rssFeed.ToString());

    XmlNodeList nl = xmlDoc.SelectNodes("/rss/channel/item");

    foreach (XmlNode xn in nl)
    {
        string title = xn["title"].InnerText;
        string link = xn["link"].InnerText;
        string desc = xn["description"].InnerText;
        string auth = xn["author"].InnerText;
        string pdate = xn["pubDate"].InnerText;

        XmlElement itemnode = xmlDoc.CreateElement("item");

        itemnode.InnerXml = "<title></title><link></link><description></description><author></author><pubDate></pubDate>";
        itemnode["title"].InnerText = title;
        itemnode["link"].InnerText = link;
        itemnode["description"].InnerText = desc;
        itemnode["author"].InnerText = auth;
        itemnode["pubDate"].InnerText = pdate;

        xmlDoc.DocumentElement.SelectNodes("/rss/channel")[0].AppendChild(itemnode);
    }

    // Output to screen
    xmlDoc.Save(Response.Output);

my rss feed

<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<channel>
<title>My RSS Feed</title>
<link>http://www.mylink.aspx</link>
<description>
</description>
<item>
  <title>Top marks</title>
  <link>http://www.mymarks.aspx</link>
  <description>
  &lt;p&gt;description field here&lt;/p&gt;
  </description>
  <author>Viv</author>
  <pubDate>Thu, 16 Aug 2012 12:10:54 GMT</pubDate>
</item>
<item>
  <title>Costa Coffee</title>
  <link>http://www.Costa.aspx</link>
  <description>
  &lt;p&gt;Costa Coffee have special offers.&lt;/p&gt;
  </description>
  <author>Mike</author>
  <pubDate>Thu, 23 Aug 2012 15:55:53 GMT</pubDate>
</item>
<item>
  <title>Celebrate success</title>
  <link>http://www.Celebrate.aspx</link>
  <description>
  &lt;p&gt;Lets all celebrate &lt;/p&gt;
  </description>
  <author>Viv</author>
  <pubDate>Thu, 22 Aug 2012 09:10:21 GMT</pubDate>
</item>
</channel>
</rss>
JK36
  • 853
  • 2
  • 14
  • 37
  • have a look at this http://stackoverflow.com/questions/344737/sorting-xml-nodes-based-on-datetime-attribute-c-xpath – saj Aug 24 '12 at 10:05

1 Answers1

4

You can do this fairly quickly and painlessly using Linq to XML.

If you parse your XML using XElement.Parse(...) you can then use OrderBy or OrderByDescending functions and alter the content pretty easily. Here is a simplified example:

XElement element = XElement.Parse(@"
<rss>
<channel>
<item title='something' pubDate='22/11/2012'/>
<item title='something2' pubDate='24/03/2012'/>
<item title='something3' pubDate='10/02/2010'/>
<item title='something4' pubDate='22/01/2011'/>
</channel>
</rss>");

var elements = element.Element("channel")
                .Elements("item")
                .OrderBy<XElement, DateTime>(e => DateTime.ParseExact(e.Attribute("pubDate").Value, "dd/MM/yyyy", null))
                .Select(e => new XElement("item",
                    new XElement("title", e.Attribute("title").Value),
                    new XElement("pubDate", e.Attribute("pubDate").Value))); // Do transform here.

            element.Element("channel").ReplaceAll(elements);

            Console.Write(element.ToString());

The XML is not going to be the same as yours, but hopefully it gives you an idea of what you could do. You can just specify XElement and XAttribute objects as content for your new XML, this outputs the following:

<rss>
  <channel>
    <item>
      <title>something3</title>
      <pubDate>10/02/2010</pubDate>
    </item>
    <item>
      <title>something4</title>
      <pubDate>22/01/2011</pubDate>
    </item>
    <item>
      <title>something2</title>
      <pubDate>24/03/2012</pubDate>
    </item>
    <item>
      <title>something</title>
      <pubDate>22/11/2012</pubDate>
    </item>
  </channel>
</rss>

I hope this is useful.

Balthy
  • 344
  • 2
  • 4
  • Hi Balthy,thanks. I Seem to be getting an error in intellisense trying to use the .OrderBy - "....XElement does not contain definition for OrderBy". – JK36 Aug 24 '12 at 11:10
  • I expect that will be that you need to make sure you have a "using System.Linq;" statement at the top of your code file. That is the main Linq namespace which contains most of the Extension Methods (including OrderBy) – Balthy Aug 24 '12 at 11:28
  • Hmmm... I just wrote that in a default Console Application. Do you have all the following using statements? using System; using System.Linq; using System.Xml.Linq; – Balthy Aug 24 '12 at 13:13
  • Yes, Ive got you code exactly as it is typed up in a .cs file. Intellisense just doesn't like that line "e => DateTime.ParseExact... – JK36 Aug 24 '12 at 13:31
  • Sorry, I'm afraid I can't think what could be going wrong. What versions of VS and .NET are you using? this was in 2010 and 4.0. You might try removing the type parameters from the OrderBy method since they can be implicitly resolved. Or you could have a play around with the order by expression and see if you can get any expression to work... – Balthy Aug 24 '12 at 13:49
  • Managed to get it working, me being dumb. Thanks. The one thing I notice is when I do the sort, it removes the the title of the rss, and I am guessing it is doing this because the title doesn't have a pubDate or author – JK36 Aug 30 '12 at 10:40