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

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

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

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

Q&A

解決済

1回答

803閲覧

XMLからHTML変換時のrowspanの値を取得したい

UG_ito_Pcorp

総合スコア13

XSLT

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

0グッド

0クリップ

投稿2020/05/20 06:04

rowspanの数がいくつでも対応できるXSLTを構築したい

Office Open XMLで作成した表組(下記)をHTMLの表組に変換するXSLTを作成しています。

イメージ説明

セルが縦方向にいくつ結合されていても対応できるXSLTを作成したいのですが、while文の様な「条件不一致でループを抜けて、そのときのカウンタの値を使用する」という処理が構築できません。

以下が、対象のXMLソースです。

※Githubへの登録が不可でしたので、ソースの整形状態を画像で、スペース無しのソースを画像の末尾に貼付しました。(文字数制限?で送信不可なため)








<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:tbl><w:tr><!-- 1行目 --><w:tc><w:tcPr/><w:p><w:r><w:t>(1行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge w:val="restart"/></w:tcPr><w:p><w:r><w:t>(1行2列目)</w:t></w:r></w:p><w:p><w:r><w:t>(2行2列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge w:val="restart"/></w:tcPr><w:p><w:r><w:t>(1行3列目)</w:t></w:r></w:p><w:p><w:r><w:t>(2行3列目)</w:t></w:r></w:p><w:p><w:r><w:t>(3行3列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge w:val="restart"/></w:tcPr><w:p><w:r><w:t>(1行4列目)</w:t></w:r></w:p><w:p><w:r><w:t>(2行4列目)</w:t></w:r></w:p><w:p><w:r><w:t>(3行4列目)</w:t></w:r></w:p><w:p><w:r><w:t>(4行4列目)</w:t></w:r></w:p></w:tc></w:tr><w:tr><!-- 2行目 --><w:tc><w:tcPr/><w:p><w:r><w:t>(2行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc></w:tr><w:tr><!-- 3行目 --><w:tc><w:tcPr/><w:p><w:r><w:t>(3行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr/><w:p><w:r><w:t>(3行2列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc></w:tr><w:tr><!-- 4行目 --><w:tc><w:tcPr/><w:p><w:r><w:t>(4行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr/><w:p><w:r><w:t>(4行2列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr/><w:p><w:r><w:t>(4行3列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc></w:tr><w:tr><!-- 5行目 --><w:tc><w:tcPr><w:vMerge w:val="restart"/></w:tcPr><w:p><w:r><w:t>(5行1列目)</w:t></w:r></w:p><w:p><w:r><w:t>(6行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge w:val="restart"/></w:tcPr><w:p><w:r><w:t>(5行2列目)</w:t></w:r></w:p><w:p><w:r><w:t>(6行2列目)</w:t></w:r></w:p><w:p><w:r><w:t>(7行2列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge w:val="restart"/></w:tcPr><w:p><w:r><w:t>(5行3列目)</w:t></w:r></w:p><w:p><w:r><w:t>(6行3列目)</w:t></w:r></w:p><w:p><w:r><w:t>(7行3列目)</w:t></w:r></w:p><w:p><w:r><w:t>(8行3列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge w:val="restart"/></w:tcPr><w:p><w:r><w:t>(5行4列目)</w:t></w:r></w:p><w:p><w:r><w:t>(6行4列目)</w:t></w:r></w:p><w:p><w:r><w:t>(7行4列目)</w:t></w:r></w:p><w:p><w:r><w:t>(8行4列目)</w:t></w:r></w:p><w:p><w:r><w:t>(9行4列目)</w:t></w:r></w:p></w:tc></w:tr><w:tr><!-- 6行目 --><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc></w:tr><w:tr><!-- 7行目 --><w:tc><w:tcPr/><w:p><w:r><w:t>(7行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc></w:tr><w:tr><!-- 8行目 --><w:tc><w:tcPr/><w:p><w:r><w:t>(8行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr/><w:p><w:r><w:t>(8行2列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc></w:tr><w:tr><!-- 9行目 --><w:tc><w:tcPr/><w:p><w:r><w:t>(9行1列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr/><w:p><w:r><w:t>(9行2列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr/><w:p><w:r><w:t>(9行3列目)</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:vMerge/></w:tcPr><w:p/></w:tc></w:tr></w:tbl></w:body></w:document>

セルの結合がない場合、<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>

作成したXSLT

作成したXSLTは以下のとおりです。

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" version="2.0"><xsl:output method="html" encoding="UTF-8" indent="yes" name="html_format"/><xsl:strip-space elements="*"/><xsl:template match="/"><xsl:apply-templates/></xsl:template><xsl:template match="w:document"><xsl:apply-templates/></xsl:template><xsl:template match="w:body"><html><body><xsl:apply-templates/></body></html></xsl:template><xsl:template match="w:tbl"><table border="1" style="border-collapse: collapse"><xsl:apply-templates/></table></xsl:template><xsl:template match="w:tr"><tr><xsl:apply-templates select="element()"/></tr></xsl:template><xsl:template match="w:tc"><xsl:variable name="tr_position" select="count(../preceding-sibling::w:tr)+1"/><xsl:variable name="tc_position" select="position()"/><xsl:variable name="current_tc_vMerge_val" select="descendant::w:vMerge/@w:val"/><xsl:variable name="next_tc_vMerge_val" select="../following-sibling::w:tr[position()=$tr_position+1]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge/@w:val"/><xsl:choose><xsl:when test="count(./w:tcPr/w:vMerge)=0"><td><xsl:apply-templates/></td></xsl:when><xsl:when test="(count(./w:tcPr/w:vMerge)=1) and ($current_tc_vMerge_val='restart')"><xsl:variable name="target_vMerge2" select="../following-sibling::w:tr[position()=2]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge//@w:val"/><xsl:variable name="target_vMerge3" select="../following-sibling::w:tr[position()=3]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge//@w:val"/><xsl:variable name="target_vMerge4" select="../following-sibling::w:tr[position()=4]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge//@w:val"/><xsl:variable name="target_vMerge5" select="../following-sibling::w:tr[position()=5]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge//@w:val"/><td><xsl:attribute name="rowspan"><xsl:choose> <!-- 以下は、rowspn上限=5迄にしか対応しない --><xsl:when test="(count(../following-sibling::w:tr[position()=2]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge)=0) or ($target_vMerge2='restart')"><xsl:value-of select="2"/></xsl:when><xsl:when test="(count(../following-sibling::w:tr[position()=3]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge)=0) or ($target_vMerge3='restart')"><xsl:value-of select="3"/></xsl:when><xsl:when test="(count(../following-sibling::w:tr[position()=4]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge)=0) or ($target_vMerge4='restart')"><xsl:value-of select="4"/></xsl:when><xsl:when test="(count(../following-sibling::w:tr[position()=5]/w:tc[position()=$tc_position]/w:tcPr/w:vMerge)=0) or ($target_vMerge5='restart')"><xsl:value-of select="5"/></xsl:when></xsl:choose></xsl:attribute><xsl:apply-templates/></td></xsl:when></xsl:choose></xsl:template><xsl:template match="w:p"><p><xsl:apply-templates/></p></xsl:template><xsl:template match="w:r"><xsl:apply-templates/></xsl:template><xsl:template match="w:t"><xsl:value-of select="."/></xsl:template></xsl:stylesheet>

以下〈xsl:template match="w:tc"〉内のchoose文を結合数無制限に対応する条件文に変更したいです。
xsl:for-eachで考えてみたのですが、都合の良い抜け方が分かりませんでした。
(現在は、結合=5つまで対応)

以上、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

xsl:for-each@select の各アイテムをコンテキストにするためのものであって、ループではありません。「抜ける」ことはありません。

ループではないものをループのように考えるのではなく、コンテキストから必要なアイテムを選択していくほうが自然です:

xml

1<xsl:function as="Q{http://www.w3.org/2001/XMLSchema}boolean" name="Q{my}cell-breaks-vmerge"> 2 <xsl:param as="element(w:tc)" name="cell" /> 3 4 <xsl:sequence select="empty($cell/w:tcPr/w:vMerge) or Q{my}cell-restarts-vmerge($cell)" /> 5</xsl:function> 6 7<xsl:function as="Q{http://www.w3.org/2001/XMLSchema}boolean" name="Q{my}cell-restarts-vmerge"> 8 <xsl:param as="element(w:tc)" name="cell" /> 9 10 <xsl:sequence select="$cell/w:tcPr/w:vMerge/@w:val = 'restart'" /> 11</xsl:function> 12 13<xsl:template as="element(td)?" match="w:tc"> 14 <xsl:if test="Q{my}cell-breaks-vmerge(.)"> 15 <td> 16 <xsl:if test="Q{my}cell-restarts-vmerge(.)"> 17 <xsl:variable as="Q{http://www.w3.org/2001/XMLSchema}integer" 18 name="current-colnum" select="count(preceding-sibling::w:tc) + 1" /> 19 <xsl:variable as="element(w:tr)+" name="next-rows" 20 select="parent::w:tr/following-sibling::w:tr" /> 21 <xsl:variable as="element(w:tr)?" name="vmerge-breaker-row" 22 select=" 23 $next-rows 24 [w:tc[$current-colnum][Q{my}cell-breaks-vmerge(.)]] 25 [1]" /> 26 <xsl:variable as="element(w:tr)+" name="vmerge-swallowed-rows" 27 select=" 28 $next-rows 29 [empty($vmerge-breaker-row) or ($vmerge-breaker-row >> .)]" /> 30 <xsl:attribute name="rowspan" select="count($vmerge-swallowed-rows) + 1" /> 31 </xsl:if> 32 33 <xsl:apply-templates /> 34 </td> 35 </xsl:if> 36</xsl:template>

投稿2020/05/26 21:53

OACleaner

総合スコア63

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

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

UG_ito_Pcorp

2020/05/28 04:01

ご教授、ありがとうございました。 まだ、十分に理解できておりませんが、じっくり勉強させていただきます。 いつも、助けていただいて感謝しております。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問