Sunday, June 16, 2002

Ok, which specification is right? Userland's RSS 0.91 specification says that the item element's description element has a maximum length of five hundred characters. However, there is no mention of this in the Netscape spec.

Now, I'm using Peter Drayton's RSS 0.91 XML schema which abides the Userland mandated five hundred character max. However, Radio itself does not seem to abide by this rule when emitting the description element. Another problem is that Radio does not emit a title and/or link element unless the post actually has one associated with it. The specification states that these two elements must always be present. Again Peter's schema is in line with this, which is causing me problems during validation.

For now, I'm working around the description problem by changing the description element from type String500 to xs:string. To work around the title and link element issues, I've added a minOccurs of zero to both elements. Everything seems to work now, but damn do I hate such loose specifications. I think the sooner we all get to the RDF/RSS 1.0, the better off we'll all be.

11:45:32 PM    

Quick follow up to today's earlier gripe about useless exception messages. It's actually worse than I described! Not only is this message useless, but it's actually completely misleading as well. :)

There is a a private method within DataSet, called EnforceConstraints, which actually handles all constraint validation. Well guess what else counts as a constraint in this code? Column length! Now, this is fine and makes complete sense, but it is not mentioned anywhere in the exception message. It mentions only "non-null, unique, or foreign-key constraints". 

Joy. Only about four hours later, having intermittently worked with that piece of the code, did I finally realize this. :|

11:30:18 PM    

Regarding ResetableIterator, I'd certainly call it a flaw. It kind of defeats the purpose of having those nice abstract classes and interfaces in the first place. [Commonality]

I agree. They tightly coupled their internals to a private subclass which disables outside parties from being able interact with the model in a transparent way. -1000 points for whatever MS developer is responsible for this OO blasphemy. ;)

10:44:33 PM    

Nothing is more frustrating than being told there's a problem, but not being given enough information to solve it. Such is the case with the ConstraintException class. My scenario happens to be that I'm populating a DataSet, which I built using ReadXmlSchema, using the ReadXml method. There's about three UniqueContraints with ForeignKeyConstraints built on top of those. All of those constraints have names and associated tables, yet when my call to ReadXml fails, I get this utterly useless message:

Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.

Ok... great, which one?? Here we have this beautiful abstract model of constraints based off the Constraint class, but this exception does nothing except say a constraint has failed. Hello!? How about at least telling me the ConstraintName and Table of the constraint that failed in the message? While we're at it, it would be even more useful to add a property to the ConstraintException class, perhaps called "FailedConstraint", which is a reference to the Constraint that failed so I could pull even more detail based off of it's concrete type if I needed to.

6:49:10 PM    

Drew has some good suggestions for the BlogToaster, expect to seem them implemented soon. [Simon Fell]

Cool, thanks Simon! ;)

6:22:15 PM    

As far as I can see, nowhere in the .NET XslTransform docs is is explicitly said that you can create extension functions that return a node-set. However, I tried a couple of times and discovered it is possible simply by making sure your function returns an XPathNodeIterator. Cool.

However, after experimenting a bit and tons of debugging, I discovered this isn't exactly true. You see, the XslTransform code doesn't expect just any kind of XPathNodeIterator implementation (it is an abstract class, after all), but instead expects you return an object of a very precise type: ResetableIterator, which is a subclass of XPathNodeIterator implemented internally inside System.Xml.dll. So, basically, I see no way you can provide your own extension function returning a custom XPathNodeIterator, which is something I was interested in doing in order to provide an extension function that could "filter" an existing node-set. [Commonality]

To address the first paragraph, it is documented here, but is very indirect. It's documented under the "XSLT Stylesheet Parameters" section in the table which indicates which .NET types map to which XPath types. Reading this would not lead you to believe that it is also possible to return these types from an script function or an extension object's method, but in fact it is. Microsoft should indicate this more clearly in the documentation.

To address your second paragraph, you're absolutely right. It does not look like you can return a custom XPathNodeIterator implementation due to this design (flaw?). However, it's important to point out that you can return an XPathNodeIterator from the base implementation of XPathNavigator::Select because it returns an XPathSelectionIterator which does derive from ResetableIterator.

Here's the test XSLT that I used to test these theories.

1:34:45 PM    

I have a very beta version of blogToaster up and running, feel free to give it a go [you need MSN Messenger]. Add "toaster@zaks.demon.co.uk" as a new contact, and start a chat session, enter "add http://www.pocketsoap.com/weblog/" and hit enter, repeat with all the URL's of the weblogs you want to get notified about. enter "list" to see the list of URL's you've registered. When BlogToaster picks up a change from weblogs.com of a URL you've registered, it'll send you a message. [Simon Fell]

Definitely cool stuff. A couple feature suggestions if I may? ;) You may have already thought of these, or perhaps even have them implemented already, but here goes:

  • "import" command: takes a url to an OPML file as a parameter. This would enable scenarios where I manage my subscriptions via some other mechasim, like Radio, then I can call "import http://radio.weblogs.com/0104813/gems/mySubscriptions.opml" and have my entire list of subscriptions registered for me automagically.
  • "removeAll" command: removes all my previously registered blog urls. This would essentially make it easy to clear all existing subscriptions and re-import them. I suppose if you wanted to get fancy you could implement import as a delta, removing any existing subscriptions that are no longer in the newly imported subscription list.

Also, I don't know if it really matters in this application's case, but this isn't technically a .NET alert. The alert system is an entirely different beast than the IM system. It actually handles things like location detection and device independant message delivery. For example, if you're not logged into Messenger, but would like to receive the message anyway, the .NET alert system can automatically send the message to a registered mobile device. All of this is transparent to the application that actually sends the alert. I don't have the specifics of the program, but IIRC it's a closed beta right now. The list of third parties does seem to be growing though. My company is going to use it to notify you when your documents are delivered. However, a major difference is that while this IM approach is free, Microsoft charges (or will be charging) third parties that want to hook into the alert architecture.

1:12:50 PM