将Google日历解析为DDay.iCal

时间:2011-04-30 10:34:13

标签: c# google-api deserialization icalendar dday

我正致力于通过Google API将Google日历解析为DDay.iCal

的应用程序

主要属性,属性易于处理 ... ev.Summary = evt.Title.Text;

问题是当我收到重复事件时,XML包含一个字段,如:

<gd:recurrence>
    DTSTART;VALUE=DATE:20100916
    DTEND;VALUE=DATE:20100917
    RRULE:FREQ=YEARLY
</gd:recurrence>

<gd:recurrence>
  DTSTART:20100915T220000Z
  DTEND:20100916T220000Z
  RRULE:FREQ=YEARLY;BYMONTH=9;WKST=SU"
</gd:recurrence>

使用以下代码:

    String[] lines = 
evt.Recurrence.Value.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);

                    foreach (String line in lines)
                    {

                        if (line.StartsWith("R"))
                        {
                            RecurrencePattern rp = new RecurrencePattern(line);
                            ev.RecurrenceRules.Add(rp);
                        }
                        else 
                        {
                            ISerializationContext ctx = new SerializationContext();
                            ISerializerFactory factory = new DDay.iCal.Serialization.iCalendar.SerializerFactory();

                            ICalendarProperty property = new CalendarProperty();

                            IStringSerializer serializer = factory.Build(property.GetType(), ctx) as IStringSerializer;

                            property = (ICalendarProperty)serializer.Deserialize(new StringReader(line));

                            ev.Properties.Add(property);
                            Console.Out.WriteLine(property.Name + " - " + property.Value);
                        }

                    }

RRULEs被正确解析,但问题是其他属性(日期时间)值是空的......

2 个答案:

答案 0 :(得分:4)

这是我正在做的事情的起点,离开the RFC-5545 spec's recurrence rule。它没有完成规范,并且可能会因某些输入而中断,但它应该让你前进。我认为这应该都是可以使用RegEx做的,而像递归正确的解析器这样重的东西会有点过分。

RRULE:(?:FREQ=(DAILY|WEEKLY|SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY);)?(?:COUNT=([0-9]+);)?(?:INTERVAL=([0-9]+);)?(?:BYDAY=([A-Z,]+);)?(?:UNTIL=([0-9]+);)?

我正在使用http://regexstorm.net/tester进行构建。

我使用的测试输入是:

  

DTSTART; TZID =美国/芝加哥:20140711T133000 \ nDTEND; TZID =美国/芝加哥:20140711T163000 \ nRRULE:FREQ = WEEKLY; INTERVAL = 8; BYDAY = FR; UNTIL = 20141101

     

DTSTART; TZID =美国/芝加哥:20140711T133000 \ nDTEND; TZID =美国/芝加哥:20140711T163000 \ nRRULE:FREQ = WEEKLY; COUNT = 5; INTERVAL = 8; BYDAY = FR; UNTIL = 20141101

     

DTSTART; TZID =美国/芝加哥:20140711T133000 \ nDTEND; TZID =美国/芝加哥:20140711T163000 \ nRRULE:FREQ = WEEKLY; BYDAY = FR; UNTIL = 20141101

样本匹配结果如下:

Index    Position    Matched String                                                 $1      $2  $3  $4  $5
0        90          RRULE:FREQ=WEEKLY;INTERVAL=8;BYDAY=FR;UNTIL=20141101           WEEKLY      8   FR  20141101
1        236         RRULE:FREQ=WEEKLY;COUNT=5;INTERVAL=8;BYDAY=FR;UNTIL=20141101   WEEKLY  5   8   FR  20141101
2        390         RRULE:FREQ=WEEKLY;BYDAY=FR;UNTIL=20141101                      WEEKLY          FR  20141101

用法如下:

string freqPattern = @"RRULE:(?:FREQ=(DAILY|WEEKLY|SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY);?)?(?:COUNT=([0-9]+);?)?(?:INTERVAL=([0-9]+);?)?(?:BYDAY=([A-Z,]+);?)?(?:UNTIL=([0-9]+);?)?";
MatchCollection mc = Regex.Matches(rule, freqPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
foreach (Match m in mc)
{
    string frequency = m.Groups[1].ToString();
    string count = m.Groups[2].ToString();
    string interval = m.Groups[3].ToString();
    string byday = m.Groups[4].ToString();
    string until = m.Groups[5].ToString();
    System.Console.WriteLine("recurrence => frequency: \"{0}\", count: \"{1}\", interval: \"{2}\", byday: \"{3}\", until: \"{4}\"", frequency, count, interval, byday, until);
}

答案 1 :(得分:-1)

这是何时使用正则表达式的一个很好的例子。试试这个进行一般解析:

\s*(\w+):((\w+=\w+;)+(\w+=\w+)?|\w+)

或者,您可能决定使用更具体模式的内容。

\s*(?:DTSTART:)(?'Start'\w+)
\s*(?:DTEND:)(?'End'\w+)
\s*(?:RRULE:)(?'Rule'(\w+=\w+;)+(\w+=\w+)?)