ulタグを省略するためのテンプレート。これで、ルート要素の直下にli要素を置ける。同様にdlタグやtableタグなんかも省略できそうだ。
<xsl:template match="/child::*[1]/li">
<xsl:if test="name(preceding-sibling::*[1]) != 'li'">
<ul>
<xsl:call-template name="groupListItems" />
</ul>
</xsl:if>
</xsl:template>
<xsl:template name="groupListItems">
<li><xsl:apply-templates select="child::node()" /></li>
<xsl:for-each select="following-sibling::*[1]">
<xsl:if test="name(self::*) = 'li'">
<xsl:call-template name="groupListItems" />
</xsl:if>
</xsl:for-each>
</xsl:template>
変換前:
<root-element>
<p>文章</p>
<li>リスト</li>
<li>リスト</li>
<p>文章</p>
<ul>
<li>リスト</li>
<li>リスト</li>
</ul>
</root-element>
変換後:
<root-element>
<p>文章</p>
<ul>
<li>リスト</li>
<li>リスト</li>
</ul>
<p>文章</p>
<ul>
<li>リスト</li>
<li>リスト</li>
</ul>
</root-element>
順序型リストだった場合はlo(List-item Ordered)要素とか何かをでっち上げて同じようにやってみようかと思ったが、素直にolタグでグループ化することにした。あまり使わないし。
xsl:call-templateで自分を呼び出す際、無限ループには気をつけなければ。この例にて、for-eachでカレントノードを変更し忘れた為無限ループをやってしまい、プロセッサを一つ再起不能にしてしまった。リブートで復活。
for-each要素が「繰り返し」だって!? 「繰り返し」としての用法しか説明していない解説って、絶対XSLTを理解してないよ。apply-templates要素だって「繰り返し」じゃん。