Reading A Sharepoint Calendar RSS Feed

Blog Post created by eironside-esristaff Employee on Feb 19, 2019

Sharepoint calendars offer an RSS feed that can be consumed by GeoEvent.  This post will show how to parse this specific input. 


The input connector 'Receive RSS' will handle subscribing to an RSS feed and parsing out the data into individual events.  In the RSS specification, each <item> segment will be converted to a GeoEvent event.  The exact structure of your RSS feed (in XML) may differ a bit (all sub-segments of item are optional), but in general it will contain the following XML segments:


titleThe title of the item.
linkThe URL of the item.
descriptionThe item synopsis.
authorEmail address of the author of the item. 
categoryIncludes the item in one or more categories. 
commentsURL of a page for comments relating to the item. 

Describes a media object that is attached to the item. It has 3 sub-segments:

url - where the enclosure is located

length - how big the enclosure is in bytes

type - a MIME type for the enclosure

guidA string that uniquely identifies the item. 
pubDateIndicates when the item was published. 
sourceThe RSS channel that the item came from. 



For the Sharepoint Calendar RSS feed, an example of the raw data is provided below. Notice that the <descripion> segment contains more than just a description. We'll have to parse that data out.

<?xml version="1.0" encoding="UTF-8"?>
<!--RSS generated by Microsoft SharePoint Foundation RSS Generator on 2/19/2019 9:08:00 AM -->
<?xml-stylesheet type="text/xsl" href="/services/ServiceCenter/_layouts/15/RssXslt.aspx?List=12345678-abcd-ef56-123a-b3c5d6e7f8ab" version="1.0"?>
<rss version="2.0">
<title>Service Center: Calendar</title>
<description>RSS feed for the Calendar list.</description>
<lastBuildDate>Tue, 19 Feb 2019 17:08:00 GMT</lastBuildDate>
<generator>Microsoft SharePoint Foundation RSS Generator</generator>
<title>Service Center: Calendar</title>
<title>Test Title</title>
<description><![CDATA[<div><b>Location:</b> San Francisco</div>
<div><b>Start Time:</b> 2/19/2019 11:00 AM</div>
<div><b>End Time:</b> 2/19/2019 12:00 PM</div>
<div><b>Description:</b> This is a test description.

There are a few line breaks here.

<b>Hello World</b></div>
<div><b>Category:</b> Meeting</div>
<author>Person Author</author>
<enclosure url="/services/ServiceCenter/_vti_bin/owssvr.dll?CS=96001&amp;Cmd=Display&amp;CacheControl=1&amp;List={12345678-abcd-ef56-123a-b3c5d6e7f8ab}&amp;ID=60&amp;Using=%2Fservices%2FServiceCenter%2FLists%2FCalendar/event.ics" type="text/calendar" />
<pubDate>Tue, 19 Feb 2019 17:03:46 GMT</pubDate>
<guid isPermaLink="true">http://serverfqdn/services/ServiceCenter/Lists/Calendar/DispForm.aspx?ID=60</guid>


Here's what I did to read/parse this feed:


  1. Create a 'Read RSS' input and let it read some events to create the GeoEvent Definition for your feed.
    1. Note, you should also be able to use a 'Poll an external website for XML' input, that is what I tested with
  2. In my case, the GeoEvent Definition looked like the following (Note you may be missing the author and enclosure segments, and the guid may be a string instead of a group).
  3. I created a copy of this definition and flattened it to look like the following
  4. Next create a GeoEvent Service
    • Add the RSS input
    • Add an output (can be anything, I used TCP out and wrote to the logger)
    • After the input add a 'Field Mapper' processor to map from your input definition to the flattened definition
    • Next, remove the HTML tags from the description using a Field Calculator processor 
      • Expression = replaceAll(desc, '<[^>]*>', '')
    • Calculate the location
      • Expression = trim( substring(desc, 9+indexOf(desc, 'Location:', 0), indexOf(desc, 'Start Time:', 0) ) )
    • Calculate the Start Time
      • Expression = trim( substring(desc, 11+indexOf(desc, 'Start Time:', 0), indexOf(desc, 'End Time:', 0) ) )
    • Calculate the End Time
      • Expression = trim( substring(desc, 9+indexOf(desc, 'End Time:', 0), indexOf(desc, 'Description:', 0) ) )
    • Caculate the Description
      • Expression = trim( substring(desc, 12+indexOf(desc, 'Description:', 0), indexOf(desc, 'Category:', 0) ) )
    • Calculate the Category
      • Expression = trim( substring(desc, 9+indexOf(desc, 'Category:', 0), length(desc) ) )


The final GeoEvent Service looks like this:


At this point,

  • You can remove line breaks by adding the following around the existing calculations above: replaceAll( [exisitngcalc], '\n', '')
  • You could use the 'Reverse GeoCode' processor to look up the location or a field calculator if location contains an x,y point.
  • Note, that your TRACK_ID may be the author instead of the link because each calendar item will have a unique link, but may be authored by the same person.
  • Finally, the start and end datetimes are strings. Currently (10.6.1) there is no way to parse these strings into dates (this may be a feature in upcoming releases).