質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

Q&A

解決済

3回答

1230閲覧

OO XMLの表組をHTMLに変換する際のrowspanの値を取得したい

UG_ito_Pcorp

総合スコア13

XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

0グッド

0クリップ

投稿2020/05/15 09:03

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による表組は以下のとおりです。
イメージ説明

生成された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のすべてのソースを記載したら、文字数制限オーバーで送信不可でした。
※何かソースが見てもらえる手段がありましたら、ご指示いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2020/05/15 10:16

> ※何かソースが見てもらえる手段がありましたら、ご指示いただけると幸いです。 GitHubにリポジトリ作ってそこにソース全部突っ込んでおけば良いんじゃないでしょうか。
UG_ito_Pcorp

2020/05/19 10:00

ご助言、ありがとうございました。 今回の質問は、一部にご回答をいただき、一部を自分で解決、一部が未回答の状態となりましたので、改めて未回答部分を整理した質問を作成し、その際にGithubを利用してみることにします。 Githubを利用したことがないため、少し勉強してからとなりますが、よろしくお願いいたします。
guest

回答3

0

未解決事項について、別途質問を作成しました。
質問名称は「XMLからHTML変換時のrowspanの値を取得したい」です。
よろしくお願いいたします。

投稿2020/05/20 06:08

UG_ito_Pcorp

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

1)についてはご回答をいただきました。OACleaner様、ありがとございました。
2)については、縦スパンが終わり、再度新たに縦スパンが始まる場合の想定が抜けていたためのエラーでした。
新たに縦スパンが始まる場合の処理を加えて、正常に数値を得ることができました。
3)については、実際のソースを展開して別途質問させていただくことにします。
4)については、上記2)が解決したら、正常に空行だけを削除するようになりました。

ありがとうございました。

投稿2020/05/19 10:08

UG_ito_Pcorp

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

xml

1<test> 2 <a/> 3 <b/> 4 <a/> 5</test>

に対して

xml

1 <xsl:template match="test"> 2 <xsl:message>a</xsl:message> 3 <xsl:apply-templates select="a" /> 4 5 <xsl:message>element()</xsl:message> 6 <xsl:apply-templates select="element()" /> 7 8 <xsl:message>node()</xsl:message> 9 <xsl:apply-templates select="node()" /> 10 </xsl:template> 11 12 <xsl:template match="a"> 13 <xsl:message select="position()" /> 14 </xsl:template>

を適用すれば、メッセージは

a 1 2 element() 1 3 node() 2 6

となります。

投稿2020/05/18 04:19

OACleaner

総合スコア72

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問