position()の正しい使い方と、該当要素のカウントのしかた
Office Open XMLで作成した表組(下記)をHTMLの表組に変換するXSLTを作成しています。
セルを縦方向に結合した部分について、HTMLのtd要素/rowspan属性で値を指定したいのですが、想定外の値が指定されてしまいます。
基本の対象XML構成は以下のとおりです。
<w:tbl> <w:tr>(行) <w:tc>(列・セル) <w:tcPr/>(セルの仕様) <w:p>(セル内のテキスト) <w:r> <w:t>(1行1列目)</w:t> </w:r> </w:p> </w:tc> (列の数だけ<w:tc>が続く) </w:tr> (行の数だけ<w:tr>が続く) </w:tbl>
セルの結合がない場合、<w:tcPr>要素は空となります。
結合したセルの最初(一番上)に相当する<w:tc>の<w:tcPr>要素には以下の内容が書き込まれます。
<w:tcPr> <w:vMerge w:val="restart"/> </w:tcPr>
結合したセルの二番目以降に相当する<w:tc>の<w:tcPr>要素には以下の内容が書き込まれます。
<w:tcPr> <w:vMerge/> </w:tcPr>
この<w:vMerge>要素とその属性値の有無を頼りにして、rowspanの値を求めましたが、思い通りの結果が得られません。
以下の点についてご教授いただけないでしょうか。
発生している問題
1 )
position()関数の理解が今イチできておらず、不明瞭な結果が出てしまいます。
position()関数は、要素ノードだけでなく、テキストノードもカウントするという解説をwebで読みました。
しかし、思い通りの値にならないので、強引にposition()の値を2で割り、-1して体裁を繕っています。
<w:tr>中の何番目の<w:tc>かを指定する正しい記述をご教授ください。
作成したXSLTは以下のとおりです。
<xsl:template match="w:tc"> <xsl:variable name="tc_position" select="(position() div 2) - 1"/> <xsl:variable name="start_tr_position" select="count(../preceding-sibling::w:tr) + 1"/>
2 )
縦スパンの終端を知るため、<w:vMerge>の有無を検知しています
<w:vMerge w:val="restart"/>を含む<w:tr>の位置は、上記の「start_tr_position」で求めています。
5つまでのセルの結合に対応するxsl:choose文を作成したのですが、なぜか1か所だけ値が想定外です。
(td rowspan="5"の部分で、"5"ではなく、"4"にならないと表が崩れる)
何で"5"になるのでしょうか?原因と対処方法をご教授ください。
<xsl:choose> <xsl:when test="count(./w:tcPr/w:vMerge) = 1"> <xsl:variable name="vMerge_val" select="descendant::w:vMerge/@w:val"/> <xsl:choose> <xsl:when test="$vMerge_val = 'restart'"> <xsl:variable name="rowspan"> <xsl:choose> <xsl:when test="count(../following-sibling::w:tr[position()=1]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge) = 1"> <xsl:choose> <xsl:when test="count(../following-sibling::w:tr[position()=2]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge) = 1"> <xsl:choose> <xsl:when test="count(../following-sibling::w:tr[position()=3]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge) = 1"> <xsl:choose> <xsl:when test="count(../following-sibling::w:tr[position()=4]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge) = 1"> <xsl:value-of select="5"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="4"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="3"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="2"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="2"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <td> <xsl:attribute name="rowspan" select="$rowspan"/> <xsl:apply-templates/> </td> </xsl:when> <xsl:when test="$vMerge_val = ''"> <xsl:apply-templates/> </xsl:when> </xsl:choose> </xsl:when> <xsl:otherwise> <td> <xsl:apply-templates/> </td> </xsl:otherwise> </xsl:choose>
3 )
方法が分からず、セルの結合数を限定した(今回は5つまで)XSLTになっていますが、結合数の制限をなしにする何か方法がないでしょうか。
本当はこの質問がメインなのですが、ここに到着するまでにも上記1)2)の問題が発生してしまいました。
よろしくお願いいたします。
4 )
生成したHTMLにやたらスペースが付いているので、XSLTの冒頭に「<xsl:strip-space elements="*"/>」を加えたところ、全く見当違いの値しか表示されなくなりました(すべてのrowspanが2になる)。
これはなぜでしょうか。とりあえず、この命令を付けずに対処していますが、後学のためにご教授ください。
残念な結果
生成されたHTMLの「<td rowspan="5">」がおかしいです。
<html xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> <body> <table border="1" style="border-collapse: collapse"> <tr> <td> <p> (1行1列目) </p> </td> <td rowspan="2"> <p> (1行2列目) </p> <p> (2行2列目) </p> </td> <td rowspan="3"> <p> (1行3列目) </p> <p> (2行3列目) </p> <p> (3行3列目) </p> </td> <td rowspan="5"> <!-- ここの値がおかしい --> <p> (1行4列目) </p> <p> (2行4列目) </p> <p> (3行4列目) </p> <p> (4行4列目) </p> </td> </tr> (以下、中略) </table> </body> </html>
以上、よろしくお願いいたします。
※XML、XSLT、HTMLのすべてのソースを記載したら、文字数制限オーバーで送信不可でした。
※何かソースが見てもらえる手段がありましたら、ご指示いただけると幸いです。
回答3件
あなたの回答
tips
プレビュー