グループをまとめるタグ その1
まず,index.xmlとindex.htmlの同じ部分を見比べてください.
<!-- index.xml --> <contents> <content href="whatsnew/index.html" name="新着"> 2002.12.1 <ul> <li><a href="saijiki/index.html">歳時記</a>に2002.11.24から2002.11.30までを追加.</li> <li><a href="biboroku/index.html">備忘録</a>のXML+XSLTに「wwwc用metaタグを作る」を追加.</li> </ul> </content> <content href="saijiki/index.html" name="歳時記"> 日々の出来事など. </content> <content href="ryokoki/index.html" name="旅行記"> 旅先での写真や駄文を. </content> <content href="hyoryuki/index.html" name="漂流記"> システム開発への私見です. </content> <content href="biboroku/index.html" name="備忘録"> 教えてもらったことやできたことを忘れないうちに. </content> <content href="zatsuroku/index.html" name="雑録"> その他雑多なものが色々. </content> <content href="links/index.html" name="リンク"> 友人・知合い,便利なソフトウェア,参考になるサイト等. </content> </contents> <!-- index.html --> <dl class="contents"> <dt><a href="whatsnew/index.html">新着</a></dt> <dd> 2002.12.1 <ul> <li><a href="saijiki/index.html">歳時記</a>に2002.11.24から2002.11.30までを追加.</li> <li><a href="biboroku/index.html">備忘録</a>のXML+XSLTに「wwwc用metaタグを作る」を追加.</li> </ul> </dd> <dt><a href="saijiki/index.html">歳時記</a></dt> <dd>日々の出来事など.</dd> <dt><a href="ryokoki/index.html">旅行記</a></dt> <dd>旅先での写真や駄文を.</dd> <dt><a href="hyoryuki/index.html">漂流記</a></dt> <dd>システム開発への私見です.</dd> <dt><a href="biboroku/index.html">備忘録</a></dt> <dd>教えてもらったことやできたことを忘れないうちに.</dd> <dt><a href="zatsuroku/index.html">雑録</a></dt> <dd>その他雑多なものが色々.</dd> <dt><a href="links/index.html">リンク</a></dt> <dd>友人・知合い,便利なソフトウェア,参考になるサイト等.</dd> </dl>
XMLの<contents>とHTMLの<dl>,XMLの<content>とHTMLの<dt>,XMLのテキストノードとHTMLの<dd>がそれぞれ対応しているのがわかります.当初作成していたHTMLを元にXMLを作ったので,要素が対応づいているのは,当然といえば当然です.
ある日気がつきました.XMLの<contents>はHTMLの<dl>を作るためだけに存在しているタグです.いらないのではないかと.つまり,繰返している<content>の最初の要素の前に<dl>を,最後の要素の後に</dl>をXSLTでつけてやれば,グループを囲っている<contents>はいらなくなります.つまり,index.xmlからcontents要素をなくし,最初と最後のcontent要素で<dl></dl>を作るXSLTを作れば,事足りそうです.
<!-- index.xml --> <content href="whatsnew/index.html" name="新着"> <!-- 一番最初のcontentの前に<dl> --> 2002.12.1 <ul> <li><a href="saijiki/index.html">歳時記</a>に2002.11.24から2002.11.30までを追加.</li> <li><a href="biboroku/index.html">備忘録</a>のXML+XSLTに「wwwc用metaタグを作る」を追加.</li> </ul> </content> <content href="saijiki/index.html" name="歳時記"> 日々の出来事など. </content> <content href="ryokoki/index.html" name="旅行記"> 旅先での写真や駄文を. </content> <content href="hyoryuki/index.html" name="漂流記"> システム開発への私見です. </content> <content href="biboroku/index.html" name="備忘録"> 教えてもらったことやできたことを忘れないうちに. </content> <content href="zatsuroku/index.html" name="雑録"> その他雑多なものが色々. </content> <content href="links/index.html" name="リンク"> <!-- 一番最後のcontentの後に</dl> --> 友人・知合い,便利なソフトウェア,参考になるサイト等. </content>
まずは簡単なサンプルで試してみることにしました.以下のsam.xmlから<dl></dl>で囲った結果を出すXSLTを作ることにします.
<!-- sam.xml --> <?xml version="1.0" encoding="utf-8"?> <root> <item>a</item> <item>b</item> <item>c</item> </root> <!-- 出力結果 --> <?xml version="1.0" encoding="utf-8"?> <dl> <dt>a</dt> <dt>b</dt> <dt>c</dt> </dl>
最初に考えたのはこんなXSLTです.これはエラーになります.開始タグ<dl>に対応する終了タグが別のタグの中にあるため,整形式のXMLではないのです.
<!-- sam.xsl --> <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml"/> <xsl:template match="/root"> <xsl:apply-templates select="item"/> </xsl:template> <xsl:template match="item[position()=1]"> <dl> <!-- 整形式XMLとしては,このタグに対応する終了タグは --> <dt><xsl:value-of select="self::node()"/></dt> <!-- ここにないといけないが,ここでは期待した出力結果が得られない --> </xsl:template> <xsl:template match="item"> <dt><xsl:value-of select="self::node()"/></dt> </xsl:template> <xsl:template match="item[position()=last()]"> <dt><xsl:value-of select="self::node()"/></dt> </dl> <!-- ここに終了タグを書くと整形式XMLではない --> </xsl:template> </xsl:stylesheet>
<dl>をタグとしてではなく,テキストとして記述することにしました.
<!-- sam.xsl -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/root">
<xsl:apply-templates select="item"/>
</xsl:template>
<xsl:template match="item[position()=1]">
<xsl:text disable-output-escaping="yes"><</xsl:text>
<xsl:text>dl</xsl:text>
<xsl:text disable-output-escaping="yes">></xsl:text>
<dt><xsl:value-of select="self::node()"/></dt>
</xsl:template>
<xsl:template match="item">
<dt><xsl:value-of select="self::node()"/></dt>
</xsl:template>
<xsl:template match="item[position()=last()]">
<dt><xsl:value-of select="self::node()"/></dt>
<xsl:text disable-output-escaping="yes"><</xsl:text>
<xsl:text>/dl</xsl:text>
<xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:template>
</xsl:stylesheet>
実行結果です.うまくいきました.
$ xt sam.xml sam.xsl <?xml version="1.0" encoding="utf-8"?> <dl><dt>a</dt><dt>b</dt><dt>c</dt></dl>
ちなみに,sam.xslは<xsl:choose>を使って書くこともできます.
<!-- sam.xsl xsl:choose版 -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/root">
<xsl:apply-templates select="item"/>
</xsl:template>
<xsl:template match="item">
<xsl:choose>
<xsl:when test="position()=1">
<xsl:text disable-output-escaping="yes"><</xsl:text>
<xsl:text>dl</xsl:text>
<xsl:text disable-output-escaping="yes">></xsl:text>
<dt><xsl:value-of select="self::node()"/></dt>
</xsl:when>
<xsl:when test="position()=last()">
<dt><xsl:value-of select="self::node()"/></dt>
<xsl:text disable-output-escaping="yes"><</xsl:text>
<xsl:text>/dl</xsl:text>
<xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:when>
<xsl:otherwise>
<dt><xsl:value-of select="self::node()"/></dt>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
この結果で,トップページを作っているXSLTにあるcontentのテンプレートも書換えます.
<!-- 修正前 --> <xsl:template match="contents"> <dl class="{name()}"> <xsl:apply-templates/> </dl> </xsl:template> <xsl:template match="content"> <dt><a href="{@href}"><xsl:value-of select="@name"/></a></dt> <dd> <xsl:apply-templates/> </dd> </xsl:template> <!-- 修正後 --> <xsl:template match="content[position()=1]"> <xsl:text disable-output-escaping="yes"><</xsl:text> <xsl:text>dl class="contents"</xsl:text> <xsl:text disable-output-escaping="yes">></xsl:text> <xsl:call-template name="content"/> </xsl:template> <xsl:template match="content"> <xsl:call-template name="content"/> </xsl:template> <xsl:template match="content[position()=last()]"> <xsl:call-template name="content"/> <xsl:text disable-output-escaping="yes"><</xsl:text> <xsl:text>/dl</xsl:text> <xsl:text disable-output-escaping="yes">></xsl:text> </xsl:template> <xsl:template name="content"> <dt><a href="{@href}"><xsl:value-of select="@name"/></a></dt> <dd> <xsl:apply-templates/> </dd> </xsl:template>