Reputation: 4424
I have an XML sitemap for a multilingual site that follows Google's specifications for multilingual sitemaps using the xhtml:link
tags.
The syntax looks like this:
<url>
<loc>http://www.example.com/url-segment/</loc>
<xhtml:link rel="alternate" hreflang="en" href="http://www.example.com/url-segment/" />
<xhtml:link rel="alternate" hreflang="de" href="http://www.example.com/de/url-segment/" />
<xhtml:link rel="alternate" hreflang="fr" href="http://www.example.com/fr/url-segment/" />
<lastmod>2016-08-09T00:41:57+12:00</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
I'm trying to make this human readable for the client using an XSLT template like this:
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td>
<xsl:variable name="itemURL">
<xsl:value-of select="sitemap:loc"/>
</xsl:variable>
</td>
<td>
<xsl:value-of select="concat(sitemap:priority*100,'%')"/>
</td>
<td>
<xsl:value-of select="concat(translate(substring(sitemap:changefreq, 1, 1),concat($lower, $upper),concat($upper, $lower)),substring(sitemap:changefreq, 2))"/>
</td>
<td>
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))"/>
</td>
</tr>
</xsl:for-each>
Which works without the xhtml:link
tags. But I'm not sure how to correctly reference the xhtml:link
tags. I've tried something like this:
<xsl:for-each select="xhtml:link">
<tr>
<td>
<xsl:value-of select="xhtml:link@href"/>
</td>
<td>
<xsl:value-of select="xhtml:link@hreflang"/>
</td>
<td colspan="2"></td>
</tr>
</xsl:for-each>
But that's not working.
What is the correct XSLT syntax for looping through/ selecting xhtml:link
tags in Google multilingual sitemaps?
Upvotes: 3
Views: 657
Reputation: 3423
I wanted the same thing as BaronGrivet (a sitemap with xhtml:link tags that displays nicely in a browser). I found an xsl template by Pedro Borges on GitHub that works quite nicely.
Rather than using xsl:for-each
to loop through each xhtml link, that template uses xsl:apply-templates
(apply-templates processes all of the child nodes of the current node}.
The key parts from Pedro’s template are:
<xsl:template match="/">
<html>
<body>
…
<xsl:apply-templates/>
…
</body>
</html>
</xsl:template>
<xsl:template match="sitemap:urlset">
…
<xsl:for-each select="sitemap:url">
…
<xsl:apply-templates select="xhtml:*"/>
…
</xsl:for-each>
…
</xsl:template>
<xsl:template match="xhtml:link">
<xsl:variable name="altloc">
<xsl:value-of select="@href"/>
</xsl:variable>
<p>
Alt language version:
<a href="{$altloc}">
<xsl:value-of select="@href"/>
</a>
–
<xsl:if test="@hreflang">
<xsl:value-of select="@hreflang"/>
</xsl:if>
</p>
</xsl:template>
Pedro's template has a lot more capability than I need (e.g. can list videos), but it was easy enough to edit the template to do what I needed.
Upvotes: 2
Reputation: 4424
I couldn't get it to recognise/ reference the xhtml:link
node using this code:
<xsl:for-each select="xhtml:link">
In the end this approach worked for me:
<xsl:for-each select="./*[@rel='alternate']">
<tr>
<td>
<xsl:value-of select="@href"/>
</td>
<td>
<xsl:value-of select="@hreflang"/>
</td>
</tr>
</xsl:for-each>
Upvotes: 3
Reputation: 7173
You are already in xhtml:link
node (in xsl:for-each). Use
<xsl:value-of select="@href"/>
and
<xsl:value-of select="@hreflang"/>
Upvotes: 0