Feed Transform Revisited
Sep 22nd, 2006 by Karen
So Bruce gave me a few tips on how to create a more effective transform that would change all different types of newsfeeds into HTML. My conversations with him helped me discover the fact that there are two different ways to develop XSLTs: push and pull methods. For a more detailed explanation check out this article on XML.com.
I guess based on the kind of XSLTs that I write was taught the pull method of writing XSLTs. This isn’t surprising because it is simpler to teach and understand. However, while this method works, according to the article it doesn’t scale up well. So I’m trying to learn how to write stylesheet that are more "push oriented". The other advantage I see of the push method is that it helps you compartmentalize the code a bit more. Based on Bruce’s advice here is what I came up with that follows his tips and the "push" method. I’d also like to thank Kevin Clarke who patiently helped me troubleshoot some of this. I’m sure this attempt is very far from perfect but is a start.
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rss1="http://purl.org/rss/1.0/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="1.0"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <xsl:template match="/"> <xsl:element name="h4"> <xsl:apply-templates select="//rss1:channel/rss1:title|/atom:feed/atom:title|//channel/title"/> </xsl:element> <xsl:element name="dl"> <xsl:attribute name="class">items</xsl:attribute> <xsl:apply-templates select="//rss1:item|//atom:entry|//item"/> </xsl:element> </xsl:template> <xsl:template match="//rss1:title|//atom:title|//title"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="rss1:item|atom:entry|item"> <xsl:element name="dt"> <xsl:element name="a"> <xsl:attribute name="href"> <xsl:apply-templates select="rss1:link|atom:link[@rel='alternate']/@href|link"/> </xsl:attribute> <xsl:apply-templates select="rss1:title|atom:title|title"/> </xsl:element> <xsl:element name="dd"> <xsl:attribute name="class">content</xsl:attribute> <xsl:attribute name="id"><xsl:text>entry_</xsl:text><xsl:number/></xsl:attribute> <xsl:choose> <xsl:when test="rss1:description|atom:summary|description"> <xsl:apply-templates select="rss1:description|atom:summary|description"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="content:encoded|atom:content"></xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:element> </xsl:template> <xsl:template match="rss1:title|atom:title|title"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="rss1:description|atom:summary|description"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="atom:content"> <xsl:copy-of select="./*"/> </xsl:template> <xsl:template match="content:encoded"> <xsl:value-of select="." disable-output-escaping="yes"/> </xsl:template> <xsl:template match="rss1:link|atom:link[@rel='alternate']/@href|link"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="atom:author/atom:name|dc:creator"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="atom:published|dc:date|pubDate"> <xsl:value-of select="."/> </xsl:template> </xsl:stylesheet>
I also used a few things I learned from what he showed me and redid my original using a simplified pull method. Even this is leaner than my original XSLT so thanks Bruce!
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rss1="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:element name="h1"><xsl:value-of select="atom:feed/atom:title|//rss1:title|//title"/></xsl:element> <xsl:element name="ul"> <xsl:for-each select="atom:feed/atom:entry|//rss1:item|//item"> <xsl:element name="li"> <xsl:element name="h2"><xsl:element name="a"> <xsl:attribute name="href"> <xsl:value-of select="atom:link[@rel='alternate']/@href|rss1:link|link"/> </xsl:attribute> <xsl:value-of select="atom:title|rss1:title|title"/> </xsl:element></xsl:element> <xsl:if test="atom:published|dc:date|pubDate"> <xsl:element name="div"> <xsl:attribute name="class">published</xsl:attribute> Published: <xsl:value-of select="atom:published|dc:date|pubDate"/> </xsl:element> </xsl:if> <xsl:if test="atom:updated"> <xsl:element name="div"> <xsl:attribute name="class">updated</xsl:attribute> Updated: <xsl:value-of select="atom:updated"/> </xsl:element> </xsl:if> <xsl:element name="div"> <xsl:attribute name="class">entrydesc</xsl:attribute> <xsl:choose> <xsl:when test="content:encoded"> <xsl:value-of select="content:encoded" disable-output-escaping="yes" /> </xsl:when> <xsl:when test="atom:content"> <xsl:copy-of select="atom:content"/> </xsl:when> <xsl:when test="atom:summary[@type='html']"> <xsl:value-of select="atom:summary" disable-output-escaping="yes" /> </xsl:when> <xsl:when test="atom:summary[@type='text']"> <xsl:value-of select="atom:summary" disable-output-escaping="no" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="rss1:description|description" disable-output-escaping="no" /> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:element> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet>

