- - PR -
XSLTで書き出した属性を使ってHTMLのテーブルを整形する方法?
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2007-03-25 19:28
はじめまして。
こちらで、再帰処理と変数処理の書き込みを見かけましたので、相談させてください ■元データ(table.xml) <?xml version="1.0" encoding="UTF-8"?> <Table trows="3" tcols="3"> <Cell crows="1" ccols="1">A1</Cell> <Cell crows="1" ccols="1">A2</Cell> <Cell crows="1" ccols="1">A3</Cell> <Cell crows="1" ccols="2">B1</Cell> <Cell crows="1" ccols="1">B3</Cell> <Cell crows="1" ccols="1">C1</Cell> <Cell crows="1" ccols="2">C2</Cell> </Table> ■書き出したデータのイメージ(table.html) <table border="1"> <tr> <td colspan="1" rowspan="1">A1</td> <td colspan="1" rowspan="1">A2</td> <td colspan="1" rowspan="1">A3</td> </tr> <tr> <td colspan="2" rowspan="1">B1</td> <td colspan="1" rowspan="1">B3</td> </tr> <tr> <td colspan="1" rowspan="1">C1</td> <td colspan="2" rowspan="1">C2</td> </tr> </table> 上のような形にしたくて、いろいろと調べて下記のようなコードを試してみたのですが、colspan属性を考慮していないため、colspan属性が1で無い限り<tr>の位置が不適切な部分に入ってしまいます(当たり前の話なのですが)。 <xsl:template match="Table"> <xsl:variable name="tyoko" select="@tcols"/> <table border="1"> <xsl:for-each select="Cell[position() mod $tyoko = 1]"> <tr> <xsl:for-each select=". | following-sibling::Cell[position() < $tyoko]"> <td colspan="{@ccols}" rowspan="{@crows}"> <xsl:value-of select="normalize-space(.)"/> </td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template> おそらく、<xsl:for-each select="Cell[position() mod $tyoko = 1]">あたりを colspan属性を加算して、なんとかすればよいのではないか?と考えているのですが。 よい方法があれば、よろしくお願いいたします。 #初歩ゆえ勉強不足な質問ですみません。 [ メッセージ編集済み 編集者: てんてん 編集日時 2007-03-25 19:53 ] [ メッセージ編集済み 編集者: てんてん 編集日時 2007-03-25 19:55 ] [ メッセージ編集済み 編集者: てんてん 編集日時 2007-03-25 19:57 ] |
|
投稿日時: 2007-03-26 00:44
てんてんさんはじめまして。
表現の中身を全部足す「sum()」という関数があるので、それを使うと以下のようにかけます。 === sample.xsl (全角スペースを半角スペースに置き換えてください) === <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="Table"> <table> <xsl:variable name="max" select="@tcols"/> <xsl:for-each select="Cell"> <xsl:variable name="sum" select="sum(preceding-sibling::Cell/@ccols)"/> <xsl:if test="$sum mod $max = 0"> <tr> <xsl:apply-templates select="."/> <xsl:for-each select="following-sibling::Cell[sum(preceding-sibling::Cell/@ccols) < $sum+$max]"> <xsl:apply-templates select="."/> </xsl:for-each> </tr> </xsl:if> </xsl:for-each> </table> </xsl:template> <xsl:template match="Cell"> <td colspan="{@ccols}" rowspan="{@crows}"><xsl:value-of select="."/></td> </xsl:template> </xsl:stylesheet> ======================================================== 考え方としては、 1、『あるCell要素の前にあるCell要素のccolsの中身』を全部足してみて 2、それがtcolsの倍数になっていればそれは行の先頭に来るCell要素なので 3、同じ行に含まれるCell要素を探して一緒に<tr>の中に入れて出力 となります。 よってccolsの値がずれていたりすると上手く動作しません。 再帰を使うともう少し高速かつccolsの値がずれていてもある程度OKなスクリプトを書けますが、 その分スクリプトが複雑になってしまうので、内容が少なければこんな感じでもいいかと思います。 |
|
投稿日時: 2007-03-26 06:54
ひだちのいろさん>
ありがとうございます! 早速、試させていただきます。 --追記です-- ばっちり動きました。大感謝です。 ありがとうございました。 これは、余談になりますが、XMLのソースをみたところccolsが連結されているパターンのほかに、crowsで縦に連結されているものがありました。 教えていただいたコードを応用して解決できないか考えてみます。 (またご相談するかもしれませんが、その時はよろしくお願いします) [ メッセージ編集済み 編集者: てんてん 編集日時 2007-03-26 18:14 ] |
1