views:

40

answers:

2

My Google sitemap renders well through XSLT fine without the xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" in the < urlset > element, however when included, my foreach statement doesn't work and nothing renders in the template. My code's below. Thanks for your help.

XML

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&gt;
<url>
<loc>{site_url}</loc>
<lastmod>{current_time format="%Y-%m-%d"}</lastmod>
<changefreq>monthly</changefreq>
<priority>0.5</priority>
</url>
</urlset>

XSL

<xsl:template match="/">
<html>
<body>
<h2>Sitemap</h2>
<table border="1">
<tr bgcolor="#9acd32">
  <th>Location</th>
  <th>Last Modified</th>
  <th>Update Frequency</th>
  <th>Priority</th>
</tr>
<xsl:for-each select="urlset/url">
<tr>
  <td><xsl:value-of select="loc"/></td>
  <td><xsl:value-of select="lastmod"/></td>
  <td><xsl:value-of select="changefreq"/></td>
  <td><xsl:value-of select="priority"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
+3  A: 

My Google sitemap renders well through XSLT fine without the xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" in the <urlset> element, however when included, my foreach statement doesn't work and nothing renders in the template

This is a FAQ.

XPath treats any unprefixed name as belonging to "no namespace". However, the elements in the provided document belong to the "http://www.sitemaps.org/schemas/sitemap/0.9" namespace -- not to "no namespace".

Therefore, the following XPath expression doesn't select any node at all:

urlset/url

Solution:

Define the "http://www.sitemaps.org/schemas/sitemap/0.9" namespace in the XSLT stylesheet and associate a prefix to it. Then use this prefix with all names that participate in any XPath expression.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:s="http://www.sitemaps.org/schemas/sitemap/0.9"
 exclude-result-prefixes="s"
>

 <xsl:template match="/">
  <html>
    <body>
      <h2>Sitemap</h2>
      <table border="1">
        <tr bgcolor="#9acd32">
          <th>Location</th>
          <th>Last Modified</th>
          <th>Update Frequency</th>
          <th>Priority</th>
        </tr>
        <xsl:for-each select="s:urlset/s:url">
          <tr>
            <td><xsl:value-of select="s:loc"/></td>
            <td><xsl:value-of select="s:lastmod"/></td>
            <td><xsl:value-of select="s:changefreq"/></td>
            <td><xsl:value-of select="s:priority"/></td>
          </tr>
        </xsl:for-each>
      </table>
    </body>
  </html>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&gt;
    <url>
        <loc>{site_url}</loc>
        <lastmod>{current_time format="%Y-%m-%d"}</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.5</priority>
    </url>
</urlset>

it correctly produces the following result:

<html>
   <body>
      <h2>Sitemap</h2>
      <table border="1">
         <tr bgcolor="#9acd32">
            <th>Location</th>
            <th>Last Modified</th>
            <th>Update Frequency</th>
            <th>Priority</th>
         </tr>
         <tr>
            <td>{site_url}</td>
            <td>{current_time format="%Y-%m-%d"}</td>
            <td>monthly</td>
            <td>0.5</td>
         </tr>
      </table>
   </body>
</html>
Dimitre Novatchev
Excellent answer! Thanks! Your explanation was very clear and the solution worked!
Julian
Do you know how to make the {site_url} into a clickable url. When I try the code below, I get the following error - "XML Parsing Error: not well-formed Location: sitename.com/sitemapxsl Line Number 194, Column 26:" with an arrow point to first left brace of the xsl syntax - Code as follows - "<td><a href='<xsl:value-of select="s:loc"/>'><xsl:value-of select="s:loc"/></a></td> "
Julian
@Julian: This is another FAQ :). Use: `<a href='{s:loc}'>`
Dimitre Novatchev
Dimitre you rock! Thanks once again! I also have another question :). Bare with me, I'm really new to XSLT having come across it two days ago. Anyhow, I've noticed IE specific rules don't work such as the following below. How do I get IE 6 and above to process them. Code as follows - '<!--[if IE 6]><style type="text/css" media="all">@import "/css/ie6.css";</style>'
Julian
@Julian: It would be best to ask your questions as questions -- not in the comments. I would be glad to answer them :)
Dimitre Novatchev
@Dimitre - Done, here's the new question - http://stackoverflow.com/questions/3844787/xslt-how-to-get-ie-consitional-statements-working-in-an-xstl
Julian
A: 

the xpath will need the namespace as a prefix, eg

{http://www.sitemaps.org/schemas/sitemap/0.9}urlset

if it was xmlns:x="http://www.sitemaps.org/schemas/sitemap/0.9" you could use

x:urlset

it looks like this page will help http://msdn.microsoft.com/en-us/library/ms950779.aspx

EDIT: I was going to post that and follow up with an example of how to use xsl to define the prefix, but Dimitre already has.

Luke Schafer