stepsection

DITA1.2から追加されたtask/stepsの要素にstepsectionというのがあります.stepとstepの間に入れるちょっとした解説のような位置づけでしょうか?これはstrict taskでもgeneral taskでも同様です.で、気になったのはHTML出力です.このstepsectionはクラスが"- topic/li task/stepsection"で要するにliなのです.HTMLでtask/stepsをolに変換していると思うのですが、このstepsectionが出てくると大変困ります.何故ってN.というリスト番号をつけてはいけないのですから...で、DITA-OT1.5.3のHTML出力を見るとちゃんとうまく回避していました.
 
<ol>
  <li>stepの内容</li>
  <li>stepの内容</li>
<ol>
<p>stepsectionの内容</p>
<ol start="3">
  <li>stepの内容</li>
  <li>stepの内容</li>
<ol>
 
というふうにolをstepsectionの前後で分割出力していました.さすがにやりますなと思って実際のスタイルシートを見たのですが([DITA-OT]/xsl/xslhtml/taskdisplay.xsl)、ちらっと見ただけでイヤになってしまいました.あいかわらずXSL1.0のままで正直なところ「スパゲティの塊」にしか見えません.やはりもう10年近くも引き継いできたスタイルシートをそう簡単にXSLT2.0には移行できないのでしょう.modeとxsl:paramでグチャグチャのスタイルシートを見て、これはとてもreference implementationにはならないなと思いました.
 
文句ばかり言っていられないので、XSLT2.0ならどう書くか?試しに作ってみました.以下がコードです.少し複雑ですが、XSLT1.0で書くよりずっと「思ったとおり」にかけます.
 
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xsl:import href="元のHTML出力のスタイルシート"/>
<xsl:template match="*[contains(@class,' task/steps ')]">
    <xsl:call-template name="processStep">
        <xsl:with-param name="prmStep" select="child::*[1]"/>
        <xsl:with-param name="prmOlStart" select="1"/>
    </xsl:call-template>   
</xsl:template>
<xsl:template name="processStep">
    <xsl:param name="prmStep" as="element()?" required="yes"/>
    <xsl:param name="prmOlStart" as="xs:integer" required="yes"/>
    <xsl:choose>
        <!-- 先頭がstep -->
        <xsl:when test="$prmStep[contains(@class,' task/step ')]">
            <!-- stepの次のグループの先頭を求める
                 stepsectionがあればそれ、なければempty
              -->
            <xsl:variable name="next"
                select="if ($prmStep/following-sibling::*[contains(@class,' task/stepsection ')])
                        then $prmStep/following-sibling::*[contains(@class,' task/stepsection ')][1]
                        else ()" as="element()?"/>
            <!-- 処理すべきstepを求める
                 次のグループの先頭があれば、そこまでのstep
         なければ以降のstep全部
              -->
            <xsl:variable name="step"
                select="if (empty($next))
                        then $prmStep | $prmStep/following-sibling::*[contains(@class,' task/step ')]
                        else $prmStep | $prmStep/following-sibling::*[contains(@class,' task/step ')][. &lt;&lt; $next ]"
                as="element()+"/>
            <!-- 処理すべきstepからolを生成 -->
            <ol start="{$prmOlStart}">
                <xsl:apply-templates select="$step"/>
            </ol>
            <!-- 次のolの開始番号を求める -->
            <xsl:variable name="nextOlStart" select="$prmOlStart + count($step)"/>
            <!-- 次があれば自分自身を呼び出す -->
            <xsl:if test="exists($next)">
                <xsl:call-template name="processStep">
                    <xsl:with-param name="prmStep" select="$next"/>
                    <xsl:with-param name="prmOlStart" select="$nextOlStart"/>
                </xsl:call-template>
            </xsl:if>
        </xsl:when>
        <!-- 先頭がstepsection -->
        <xsl:when test="$prmStep[contains(@class,' task/stepsection ')]">
            <!-- stepsectionの次のグループの先頭を求める
                 stepがあればそれ、なければempty
              -->
            <xsl:variable name="next"
                select="if ($prmStep/following-sibling::*[contains(@class,' task/step ')])
                        then $prmStep/following-sibling::*[contains(@class,' task/step ')][1]
                        else ()" as="element()?"/>
            <!-- 処理すべきstepsectionを求める
                 次のグループの先頭があれば、そこまでのstepsection
         なければ以降のstepsection全部
              -->
            <xsl:variable name="stepSection"
                select="if (empty($next))
                        then $prmStep | $prmStep/following-sibling::*[contains(@class,' task/stepsection ')]
                        else $prmStep | $prmStep/following-sibling::*[contains(@class,' task/stepsection ')][. &lt;&lt; $next ]"
                as="element()+"/>
            <!-- 処理すべきstepsectionを処理 -->
            <xsl:for-each select="$stepSection">
                <xsl:apply-templates select="."/>   
            </xsl:for-each>
            <!-- 次があれば自分自身を呼び出す -->
            <xsl:if test="exists($next)">
                <xsl:call-template name="processStep">
                    <xsl:with-param name="prmStep" select="$next"/>
                    <xsl:with-param name="prmOlStart" select="$prmOlStart"/>
                </xsl:call-template>
            </xsl:if>
        </xsl:when>
        <xsl:otherwise>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
<!-- stepとstepsectionのテンプレートは字数制限で省略-->
</xsl:stylesheet>
 
やはりプログラミング言語は思ったストリー通りにかけないとダメですね.XSLT1.0で歯を食いしばって書いてもメンテナンス性が悪くなるだけです.上記のスタイルシートで出力したHTMLの画面はこんな感じになります.
 
イメージ 1