Update to “One additional note:” below: Uh, found the link, and it seems the way I remember things being handled is different than it is actually handled. In short, they handle things the same way.
So I guess my whole rant is effectively pointless, and meaningless.
On a related note: that really bites! ;)
EXTENDED POINT: You would have thought that making a fool out of myself on the Atom syntax mailing list when MS first announced they were going to handle things this way would have been enough to keep me from making a fool out of myself in the follow-up below.
My only response to this is,
You don’t know me very well, do you? ;)
Okay, now that we have that clear, here’s why what I stated below is a bunch of bologna,
99% of the worlds population are (somewhat) normal.
The other 1% of us are not. Of course, “the other 1%” refers to us geeks.
To us geeks, we get web feeds. We’ve adopted them as part of our daily lifestyle.
The rest of the normal people have not.
As such, MS, Apple, and any other company in the business of presenting content served up by web feeds have to be as flexible as they can be, providing a consistent user experience from one web feed to the next.
With this in mind, the reason why,
* <feed is enough information to pass the XML file to the web feed rendering engine
* <?xml-stylesheet ... must be ignored
is the fact that the user experience MUST be consistent regardless of the edge cases where someone (like me) has chosen to preface the top-most parent of an XML document with something like feed-transform-init, or someone (again, like me) would REALLY like to invoke a browser-based transformation of a web feed using the <?xml-stylesheet ... processing instruction.
The truth of the matter is that folks (you guessed it > like me ;-)) can find other ways to hack around things of this nature (e.g. using a bootstrap XML file that imports an external web feed via the document function (yo Opera, < See why the document function is so important? :D) for rendering locally.) where as normal people who visit a web site, see the little orange icon “light up”, and click it, expect to see whats contained in the web feed rendered in a consistent manner.
If they don’t,
Support Nightmare from Hell is the first thing that comes to mind, but without a doubt, there are other reasons.
Oh, by the way, want a neat little trick to ensure your blog visitors are only given access to your Atom feed, while not breaking applications who haven’t caught up with the times and have a hard time either understanding what application/atom+xml means, or simply can not render an Atom feed?
Visit my personal blog in IE7, click the right hand drop-down next to the lit-up orange icon, and then view source for the answer. ;) :D
Oh, and make sure you serve up (you will need to actually change what your web server sends as the mime-type for each file; setting these values in html/head/link/@type is not sufficient, although this is important as well) your,
* RSS “2.0″ feed with a mime-type of application/xml,
* RSS+RDF feed as application/rdf+xml,
Also, to ensure those applications that do not understand application/atom+xml can still figure out how to render your Atom feed, create two Atom feeds;
* feed.atom
* atom.xml
Serve up,
* feed.atom with a mime-type of application/atom+xml, and
* atom.xml with a mime-type of application/xml
Shake (never stir!) for 30 seconds.
Enjoy!
—
Update: I was just looking at some of these files inside of Safari on my Mac, and discovered that when I attempt to look at the init-process.xml file it seems to think its a web feed, and attempts to render it as such. Like me, you might be asking yourself, “Why on earth would Safari think this is a web feed?” to which I would reply “Exactly! Let’s find out…”
Oh, you’ve gotta be kidding me!
<?xml version="1.0" encoding="UTF-8"?>
<feed-transform-init xmlns="http://xsltransformations.com/webfeeds/feed-transform-init" xml:base="file:///G:/xslt/trunk/module/feedAggregation/">
...
</feed-transform-init>
NOTE: To those of you that don’t eat, breathe, and dream in XML, it seems that whomever is responsible for building the XML parser that Safari uses, wrote it in such a way as to read the first five(5) characters immediatelly following the XML declaration and any potential line breaks, DTD-related markup, and processing-instructions, and if this aforementioned sequence of characters matches,
<feed
regardless of what follows, it assumes its an Atom feed, and hands it off to the feed processing engine for handling.
Apple, WTF? I mean, one could argue that you are saving precious CPU cycles by ignoring the more important namespace declaration, or you could further argue the “what if there isn’t a namespace?”, but,
1) How many cycles do you honestly think you’re saving?
2) This isn’t RSS “2.0″! People who actually care about important things like XML namespaces, are using RSS 1.0+RDF and/or Atom. This would fly if the first four(4) characters (after the same list of mentioned items) were <rss (the whole refusal to add a namespace to the rss “2.0″ “spec” thing >> Don’t get me started! ;)), but they’re obviously not.
Okay, fair enough… as long as you’re not doing something as incredibly lame as ignoring any <?xml-stylesheet ... processing instructions (haven’t checked) if the first five(5) characters of the XML data are <feed, its not really all that horrible of an XML sin.
But its definitely borderline, and none-the-less lame! ;) :D
One additional note: In case you want an example of how to properly deal with this type of a situation inside of a browser, the way the IE7 team chose to handle things is the right way. I’ll find the link and update accordingly.
—
Update: One last check-in for the day, via the latest check-in notes:
The process is now initialized by running init-process.xml against aggregation.xsl. init-process.xml allows you to set the xml:base for the output directory, the file for capturing the result output, a document for catching the files that caused errors and therefore could not be processed, and then a list of the opml files containing the xml URL’s for processing.
I’ve also taken a first stab at adding the source element with the proper child elements, although its obvious that this area needs some considerable work.
[Updated XSLT]
[init-process.xml]
[error-document] NOTE: Just noticed I need to correct the namespace output for this file. Will do that with the next check-in.
[current output] NOTE: This files weighs in at about 2 megs — if your on a slow connection I wouldn’t bother clicking.
—
Update: As per the latest check-in notes:
As hard as it was to overcome the urge to not implement support for OPML as an input format, real world data and real world use-cases are forcing my hand.
Damn.
[Updated XSLT]
[OPML 1.1-based Test Doc]
[OPML 2.0-based Test Doc]
I need to build in the ability properly handle errors such as 4xx, and other common errors. There are a couple of ways to do this, but I need to think this through to make sure this gets properly handled in all possible cases in which an error can be thrown (e.g. invalid byte 1 of 1-byte UTF-8 sequence, invalid XML (e.g. improperly escaped content in the description element of RSS-based feeds, undeclared entities, etc…)
In the mean time I plan to work on some of the other missing pieces, and then come back to this once I’ve thought things through.
—
Update: Latest Check-In[Revision 26]: Added ability to set the default header elements and values via an external XML initilialization file.
Please see related description below.
—
As per my post to the LLUP group development list (which anyone is free to join, by-the-way) last Friday Night/early Saturday morning,
this gets us about 2/3rd’s of the way. Still need to write a date conversion utility, and then deal with all of the serialization issues, as well as the mapping of attributes from Atom 0.3 to 1.0. There’s also a need to (after proper serialization of the data contained inside of the description tag of RSS+RDF, and the other Pseudo RSS format.) generate the proper type attribute value of the content element based on the determination as to what is contained inside of the RSS ‘description’ element.
…Related files: http://xslt.googlecode.com/svn/trunk/module/feedAggregation/
The last check-in note:
current snapshot of the output that is produced for an Atom 0.3, RSS+RDF, RSS “2.0″, as well as an existing Atom 1.0 feed.
The current output can be see @
http://xslt.googlecode.com/svn/trunk/module/feedAggregation/output.xml
You can checkout this particular set of files via,
svn co http://xslt.googlecode.com/svn/trunk/module/feedAggregation/ feedAggregation
Further instructions can be found @ http://code.google.com/p/xslt/source
We need this for the LLUP/Blip Messaging project for various reasons, so I need to get this finished in the next few days. But If anybody finds they have interest, and decides to plug a few of the missing holes before I have a chance to, by all means, please do, and then let me know and I will give you check-in permissions to the GoogleCode-based XSLT project I started last week to begin a group-based development effort to create reusable XSLT modules, functions, and packages that can easily be referenced using the HTTP-accessible GoogleCode SVN repository (e.g. <xsl:import href="http://xslt.googlecode.com/svn/trunk/module/feedAggregation/formats/atom-0.3.xsl" />) for testing, and then checked-out for local use when they prove to work for your particular needs.
Worth noting: I’ve also added Dimitres FXSL (1.2 for XSLT 1.0, and a snapshot of the current CVS for XSLT 2.0), my own AtomicXML code base, Russ Miles and my AspectXML code base, some tutorials, and general samples here and there that I had laying around. If you have something you would like to add to the collective pot, please let me know.
Thanks, please share, and enjoy!
NOTE: All code that is not in the ‘ext’ folder contained in the trunk is licensed under the new BSD license.
NOTE: What was here for like five minutes, I’ve replaced with an 1/8th of the code after pulling my head out and realizing the code to generate the output already existed, and I simply needed to apply-templates on the xml file to get the desired result :D
For example [via http://xslt.googlecode.com/svn/trunk/module/feedAggregation/default-header-data.xml],
<?xml version="1.0" encoding="UTF-8"?>
<feed
xml:lang="en"
xml:base="http://xslt.googlecode.com/svn/trunk/module/feedAggregation/"
xmlns:date="http://xsltransformations.com/functions/date"
xmlns="http://www.w3.org/2005/Atom">
<title>Feed Aggregation Test</title>
<link rel="self" type="application/atom+xml" href="output.xml"/>
<updated>
<date:output current="yes" format="[Y]-[M]-[D]T[H]:[m]:[s][Z]"/>
</updated>
<subtitle>Header data for test output of the various web feeds formats</subtitle>
<id>tag:xsltransformations.com/,2006://8</id>
<generator version="0.1" uri="http://www.xameleon.org">Xameleon</generator>
<rights>Copyright (c) 2006, M. David Peterson</rights>
</feed>
Related XSLT [via http://xslt.googlecode.com/svn/trunk/module/feedAggregation/aggregation.xsl
<xsl:variable name="default-header-data" select="document('./default-header-data.xml')/atom:feed"/>
<xsl:strip-space elements="*"/>
<xsl:output name="xml" method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="subscriptions"/>
</xsl:template>
<xsl:template match="subscriptions">
<xsl:result-document format="xml" href="file:///{concat(@saveResultBase, $default-header-data/atom:link/@href)}">
<feed xml:lang="en"
xml:base="{$default-header-data/@xml:base}">
<xsl:apply-templates select="$default-header-data/*"/>
<xsl:apply-templates select="feed"/>
</feed>
</xsl:result-document>
</xsl:template>
<xsl:template match="feed">
<xsl:apply-templates select="document(@uri)/*" mode="init"/>
</xsl:template>
<xsl:template match="*" mode="init">
<xsl:apply-templates select="atom:entry|channel|rdf:channel|rss:channel|atom0:entry"/>
</xsl:template>
<xsl:template match="date:output">
<xsl:if test="@current = 'yes'">
<xsl:value-of select="format-dateTime(current-dateTime(), @format)"/>
</xsl:if>
</xsl:template>


Excellent, now I will be able to tranform everything into AtomOwl:
http://bblfish.net/work/atom-owl/2006-06-06/
Hey Henry,
Oh, nice! I didn't know about this project. This will actually provide a nice use-case to test against.
I'll put some more time into this later this afternoon after returning from a meeting with one of the folks pulling together all of the official/legal business paperwork for the Viberavetions project (still VERY MUCH alive, btw, to those of you who might be wondering -- just can't talk about most of it at this stage much past "In Process" :D).
I'll update this post accordingly.
Thanks for the info regarding atom-owl. Looks interesting!
Nice work!
Incidentally, a few years ago Morten Frederikson did an anyfeed to RSS 1.0 normaliser, I used it extensively in my (RDF-backed) syndication play. But post-Atom I think the Atom/OWL model is going to be more useful, so (a little ironically) even the RSS 1.0 to Atom will be useful in RDF terms...
I'm planning on getting the Atom2AtomOwl XSLT sorted out this week (I did one ages ago, but was unfinished and is now out of date), see
http://esw.w3.org/topic/GrddlAtom
Hey Danny,
Thanks! We should try and coordinate our efforts such that the areas we're each working on can compliment each of our current efforts. I can be pretty flexible, so if you want to let me know where you think I should place the primary focus, and I will adapt accordingly.