Re: Atom の XSLT ― 2007年01月21日 18時30分
「Atom の XSLT - Mozilla Firefox Thunderbird の拡張あれこれ-MEMO」について。
XPath 式の中で接頭辞 atom が使われていますが、これに関連付けられた名前空間 URI は古いものです。また、デフォルト名前空間が宣言されておらず、xsl:output 要素の method 属性の値が html となっていますが、この状態だと空要素の終了タグが出力されないなど、出力結果が XML として不正になる可能性があります。application/xhtml+xml として出力するなら、デフォルト名前区間を XHTML にして、method 属性には値 xml を指定したほうがいいでしょう。細かい点ですが XHTML の公開識別子にも誤りがあります。
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml"
version="1.0">
<xsl:output
method="xml"
encoding="utf-8"
omit-xml-declaration="yes"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
indent="yes"
media-type="application/xhtml+xml"/>
タイトル部分のリンク先が意図したものと異なる点については、XPath 式のマッチが失敗し、生成された a 要素の href 属性の値が空になっているのが原因です。式 "/" にマッチするのは文書ノードであり、ルート要素ノードではありません。カレントノードである文書ノードの子要素はルート要素だけです。ルート要素は atom:link 要素ではないのでマッチに失敗しているのです。
<xsl:template match="/">
...
<a href="{atom:feed/atom:link[@rel='alternate']/@href}">
atom:entry 要素を処理するのに xsl:for-each 要素を使っていますが、xsl:for-each はその内容がテンプレートとなります。元のままでは内容がないため何も生成されません。xsl:template 要素に指定したテンプレートを使いたいときは xsl:apply-templates 要素を使う必要があります。
<xsl:template match="atom:feed">
<div id="wrapper">
<xsl:apply-templates select="atom:entry" />
</div>
</xsl:template>
atom:entry 要素に対するテンプレート内の XPath 式で名前空間が指定されていません。また、xsl:value-of 要素だと単一のテキストノードに変換されてしまうので、atom:content 要素の内容は xsl:copy-of 要素を使い子孫要素も含めてコピーしたほうがいいでしょう。
<xsl:template match="atom:entry">
<div class="contents">
...
<xsl:copy-of select="atom:content/xhtml:div"/>
</div>
</xsl:template>
以上をひとつの XSLT 文書にまとめてみました。ただ、私自身 XSLT に触れるのは久々ですし、もっと効率のいい、またはお行儀のいい書き方があるならどなたか教えていただけると幸いです。
最近のコメント