Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Formatting a google news feed

Status
Not open for further replies.

daint

Technical User
Oct 4, 2000
46
0
0
GB
Hello,

I've been trying to format the google rss feed in a way that the top news item would have the associated image, then 4-5 more news items are listed, but that's all. A lot like the news is shown on the right hand side of
Using a xsl document, I can list every detail in the feed, or I can list just the titles, but can't seem to get it how I want it. I've used just simple xsl stylesheets found on the net due to my lack of knowledge.

Can anyone point me in the right direction, is this a simple thing to do?

The rss feed I'm trying to format is
And here is the xsl sheet so far

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="xml" encoding="iso-8859-1" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="*">

<!--SETS UP THE TABLE PROPERTIES-->
<table border="0" cellspacing="3">

<!--SETS UP THE TITLE CELL PROPERTIES-->
<tr><td valign="top" align="center" bgcolor="#EFEFEF" >

<!--SETS UP THE TITLE LINK-->
<a>
<xsl:attribute name="href">
<xsl:value-of select="*[local-name()='channel']/*[local-name()='link']"/>
</xsl:attribute>
<xsl:attribute name="target">
<xsl:text>top</xsl:text>
</xsl:attribute>
<xsl:value-of select="*[local-name()='channel']/*[local-name()='title']" disable-output-escaping="yes"/>
</a>
</td></tr>

<!--SETS UP THE CONTENT AND TABLE CELLS FOR EACH NEWS ITEM-->

<xsl:for-each select="//*[local-name()='item']">
<tr><td valign="top" bgcolor="#E7F7FF">

<a>
<xsl:attribute name="href">
<xsl:value-of select="*[local-name()='link']"/>
</xsl:attribute>
<xsl:attribute name="target">
<xsl:text>top</xsl:text>
</xsl:attribute>
<xsl:value-of select="*[local-name()='title']" disable-output-escaping="yes"/>
</a><br></br>
<xsl:value-of select="*[local-name()='description']" disable-output-escaping="yes"/>
<br></br>
</td></tr>
</xsl:for-each>

<!--CLOSES THE TABLE-->
</table>

</xsl:template>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>


Thanks
 
The golden rule in good web design is semantics. Once you have that sorted, everything else is easy. Tables should be reserved for tabular data only. Much better to hack the CSS than have a page with unclear structure.

This news feed is not very good, it requires a bit of string hacking to get the picture out. Anyways, this should give you some ideas:
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:output method="xml" indent="yes" encoding="iso-8859-1" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="[URL unfurl="true"]http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"[/URL] omit-xml-declaration="yes"/>
  <xsl:template match="/">
    <xsl:apply-templates select="rss/channel"/>
  </xsl:template>
  <xsl:template match="channel">
    <html>
      <head>
        <title>This is the news</title>
        <style type="text/css">
div.newsCategory
{
  width: 400px;
  border: 1px solid blue;
  margin: 5px;
  font-size: 14px;
}
div.newsHeader
{
  padding-left: 5px;
  color: white;
  background-color: blue;
  font-size: 18px;
}
div.newsCategory ul
{
  margin: 5px;
}
div.newsCategory ul li
{
  width: 390px;
  margin: 2px 0px 2px 0px;
}
div.newsCategory ul li a
{
  text-decoration: none;
}
div.newsCategory ul li a:hover
{
  text-decoration: underline;
}
div.newsCategory ul li.first
{
  font-weight: bold;
}
div.newsCategory ul li.first img
{
  float: left;
  margin-right: 2px;
}
        </style>
      </head>
      <body>
        <div id="news">
          <!-- Group the items by apply templates to items uniquely identified by category -->
          <xsl:apply-templates select="item[not(category = preceding-sibling::item/category)]" mode="category"/>
        </div>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="item" mode="category">
    <div class="newsCategory">
      <div class="newsHeader">
        <xsl:value-of select="category"/>
      </div>
      <ul>
        <!-- List all items that match the current category -->
        <xsl:apply-templates select="../item[category = current()/category]" mode="story"/>
      </ul>
    </div>
  </xsl:template>
  <xsl:template match="item" mode="story">
    <li>
      <xsl:choose>
        <!-- Display picture for first item in list -->
        <xsl:when test="not(category = preceding-sibling::item/category)">
          <xsl:attribute name="class">first</xsl:attribute>
          <xsl:variable name="image" select="substring-before(substring-after(description, '&lt;img'), '&gt;')"/>
          <xsl:variable name="src" select="substring-before(substring-after($image, 'src='), ' ')"/>
          <xsl:variable name="width" select="substring-before(substring-after($image, 'width='), ' ')"/>
          <xsl:variable name="height" select="substring-before(substring-after($image, 'height='), ' ')"/>
          <img src="{$src}" alt="{category} headline picture" width="{$width}" height="{$height}"/>
        </xsl:when>
        <!-- Draw line for all others in list -->
        <xsl:otherwise>
          <hr/>
        </xsl:otherwise>
      </xsl:choose>
      <a href="{link}">
        <xsl:value-of select="title" disable-output-escaping="yes"/>
      </a>
    </li>
  </xsl:template>
</xsl:stylesheet>

Jon

"I don't regret this, but I both rue and lament it.
 
That looks really good, thanks.

But the problem I have is limited space, I could put that output into an iframe, but I was looking at a more breif way of showing it, as in, the amount of space yahoo.co.uk provides. But while keeping one or two images.

I suppose I could do with a way of instead of the for-each bits, I need to grab them one at a time.

All this rss and xsl stuff is very good, I thought it was just a way of giving data, but there's a lot more to it than that.

Thanks for the help so far.
 
Limited space just requires you to format the output differently. Play around with the CSS. Maybe choose only three categories:
Code:
<body>
  <div id="news">
    <xsl:apply-templates select="item[category = 'Top Stories'][1]" mode="category"/>
    <xsl:apply-templates select="item[category = 'Sport'][1]" mode="category"/>
    <xsl:apply-templates select="item[category = 'Entertainment'][1]" mode="category"/>
  </div>
</body>

Jon

"I don't regret this, but I both rue and lament it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top