Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT does not work when I include xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"

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">
<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>
like image 490
Julian Avatar asked Oct 01 '10 02:10

Julian


2 Answers

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">
    <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>
like image 85
Dimitre Novatchev Avatar answered Nov 08 '22 06:11

Dimitre Novatchev


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.

like image 27
Luke Schafer Avatar answered Nov 08 '22 06:11

Luke Schafer