エントリ一覧のテーブル表示でセルが表示されない

「まったく何も分からない・・・」そんなユーザーさんの為のフォーラムです。どんなご質問でもお気軽にどうぞ。
返信
salsa
記事: 5
登録日時: 2008年11月18日(火) 00:29

エントリ一覧のテーブル表示でセルが表示されない

投稿記事 by salsa » 2008年11月19日(水) 23:46

マニュアルにある「6.3.11エントリ一覧のテーブル表示機能」を
試しています。
3列のテーブルを出力するようにし、
現在、4つのエントリ(テスト1〜テスト4)を追加しました。
ところが、下記のように、テーブルの2行目には1つのセルしか出力されていません。

コード: 全て選択

<body>
<table border="1">
<tr>
<td><div class="inst-name">テスト1</div></td>
<td><div class="inst-name">テスト2</div></td>
<td><div class="inst-name">テスト3</div></td>
</tr>
<tr>
<td><div class="inst-name">テスト4</div></td>
</tr>
</table>
</body>

エントリの数が少ない場合も、
下記のように1行に3列のセルが出力されるようにはならないのでしょうか?

コード: 全て選択

<body>
<table border="1">
<tr>
<td><div class="inst-name">テスト1</div></td>
<td><div class="inst-name">テスト2</div></td>
<td><div class="inst-name">テスト3</div></td>
</tr>
<tr>
<td><div class="inst-name">テスト4</div></td>
<td></td>
<td></td>
</tr>
</table>
</body>

念のため、スキーマ定義とデザイン定義を下記に掲載しておきます。

コード: 全て選択

<?xml version="1.0" encoding="UTF-8"?>
<schema name="test" caption="test" >
	 <data name="instname" type="text" output="text2" caption="名前" />
</schema>

コード: 全て選択

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="EUC-JP" omit-xml-declaration="yes" />
<xsl:template match="/entrylist">

<table border="1">
<xsl:for-each select="row">
<tr>
<xsl:for-each select="entry">
<td>
<div class="inst-name"><xsl:value-of select="instname" disable-output-escaping="yes" /></div>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>


<div class="posi-center">
<xsl:for-each select="navi">
<xsl:for-each select="prev">
<a href="{@href}"><<前のページへ</a>|
</xsl:for-each>
<xsl:for-each select="next">
<a href="{@href}">次のページへ>></a>
</xsl:for-each>
</xsl:for-each>
</div>

</xsl:template>
</xsl:stylesheet>

お手数おかけしてすみません。
どうぞよろしくお願い致します。

blue
パワーユーザー
記事: 70
登録日時: 2005年1月31日(月) 20:49

投稿記事 by blue » 2008年11月21日(金) 17:43

スタイルシートで
empty-cells:show;
を設定してください

salsa
記事: 5
登録日時: 2008年11月18日(火) 00:29

投稿記事 by salsa » 2008年11月21日(金) 22:30

blue様

コメントありがとうございます。

教えていただいたCSSを設定してみましたが
ダメでした・・・

これまで「empty-cells: show; 」を使ったことがなかったので
私も調べてみたのですが、

コード: 全て選択

<td>あああああ</>
<td>いいいいい</td>
<td></td>
といったように、<td>内が空の場合、
ボーダー指定していても、ボーダーが表示されないようですね。

その場合、「empty-cells: show; 」で
<td>内が空でも、ボーダーを表示できるようになるということが
分かりました。

私の場合は、

コード: 全て選択

<table>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
</tr>
</table>
という具合に、2つ目の<tr>内に
<td></td>がひとつしか出力されないのです・・・


例えば、3×3(9つのセル)のテーブルに対し、
7つしかエントリを追加しない場合、
7つのセルしか出力されない仕様なのでしょうか。

blue様、せっかくアドバイスいただいたのに
前の説明が不十分なため、
お手数おかけしてすみません。

blue
パワーユーザー
記事: 70
登録日時: 2005年1月31日(月) 20:49

投稿記事 by blue » 2008年11月22日(土) 15:04

 いえいえ、こちらこそ安直に答えてしまってすみません。
 エントリが無い場合、<td></td>ごと出力されない、当然てば当然でした。
 1行に3列のセルを表示させたいということで、考え方としては、エントリが3の倍数じゃなかったら〜という条件分岐をデザインすれば良いかと。

コード: 全て選択

<xsl:if test="(count(entry) mod 3) != 0">3の倍数じゃないよ</xsl:if>
と、コレじゃ不充分ですね。

コード: 全て選択

余りが2の場合はセルを1個追加する
<xsl:if test="(count(entry) mod 3) = 2"><td></td></xsl:if>
余りが1の場合はセルを2個追加する
<xsl:if test="(count(entry) mod 3) = 1"><td></td><td></td></xsl:if>
でどうかな?

salsa
記事: 5
登録日時: 2008年11月18日(火) 00:29

投稿記事 by salsa » 2008年11月23日(日) 00:12

blue様
再度コメントありがとうございます。

教えていただいた方法、早速、試させていただきました。
デザイン定義に下記の通り追加してみました。
count(entry)のentryには、データ名を入れました。

コード: 全て選択

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="EUC-JP" omit-xml-declaration="yes" />
<xsl:template match="/entrylist">

<table border="1">
<xsl:for-each select="row">
<tr>
<xsl:for-each select="entry">
<td>
<div class="inst-name"><xsl:value-of select="instname" disable-output-escaping="yes" /></div>
</td>
<xsl:if test="(count(instname) mod 3) = 2"><td></td></xsl:if>
<xsl:if test="(count(instname) mod 3) = 1"><td></td><td></td></xsl:if>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>

</xsl:template>
</xsl:stylesheet>

セルが増えました!

ところが・・・
すべてのセルの後ろに、2つずつセルが増えてしまいました。
1行目が12例、2行目は3列という具合です。

最後の行だけ、セルを追加させることは可能でしょうか。

あるいは、教えていただいたコードの組み込み方が
間違えているのかもしれませんが。
count(entry)のままだと、セルは増えなかったので
データ名に変えたのは間違いだったのでしょうか。


xslの知識が皆無なので、
マニュアルに書かれている方法を色々と組み合わせるしか出来なくて・・・
ifで何とかできるかも・・・と思ったものの
具体的にどうすればいいのか、さっぱり分からなかったので
とてもありがたいです。

salsa
記事: 5
登録日時: 2008年11月18日(火) 00:29

投稿記事 by salsa » 2008年11月23日(日) 01:38

「エントリ一覧の「最後」だけ特殊な出力をしたい場合」というのを見つけたので
blue様に教えて頂いたコードに付け加えました。

コード: 全て選択

〜
<xsl:if test="position()=last()">
<xsl:if test="(count(instname) mod 3) = 2"><td></td></xsl:if>
<xsl:if test="(count(instname) mod 3) = 1"><td></td><td></td></xsl:if>
</xsl:if>
〜

そうすると、各セルの後ろにセルが2つ追加されていたのが
テーブルの各行の最後にのみ
セルが2つ追加されるようになりました。

しかし、セルを追加したいのは
最終行のみなので、あと一歩ということろです。

素人考えですが、

テーブルの最終行のセルの数が1つだった場合は、
最終行にセルを2つ追加する

テーブルの最終行のセルの数が2つだった場合は、
最終行にセルを1つ追加する

という条件分岐は可能なのでしょうか。
また可能な場合、具体的なコードを教えていただけたら
ありがたいです。

blue
パワーユーザー
記事: 70
登録日時: 2005年1月31日(月) 20:49

投稿記事 by blue » 2008年11月23日(日) 18:20

 あわわ。思ったより深みに嵌ってしまいましたね。
 改めてマニュアルを見てみると、
そこでCMS Designer 側で事前にエントリ一覧をn個ごとにブロック化しておくことで、デザイン (XSLT)側ではそのブロック単位にTRタグを出力するだけで良いようにしました。
 この「ブロック化」ってとこがミソのような気が。つまり、cols数ずつ括られたブロック単位でposition()やlast()といった関数が働くので、各行末にセルが出て来るようです。
 ならば、この括りから出してやればいいですよね。

コード: 全て選択

<xsl:for-each select="row">
<tr>
<xsl:for-each select="entry">
<td></td>
</xsl:for-each>
<xsl:if test="position()=last()">
<xsl:if test="(count(entry) mod 3) = 2"><td></td></xsl:if>
<xsl:if test="(count(entry) mod 3) = 1"><td></td><td></td></xsl:if></xsl:if>
</tr>
</xsl:for-each>
 これで、last()が出力データの一番最後を指してくれるはず。

salsa
記事: 5
登録日時: 2008年11月18日(火) 00:29

投稿記事 by salsa » 2008年11月23日(日) 18:38

blue様

ありがとうございます〜(涙
もうバッチリでした!

昨夜は明け方まで、XSLのサイトを見たりしながら
あ〜でもないこ〜でもないと・・・

blueさんのアドバイスがなければ、きっと解決できませんでした。
ありがとうございました。
心より感謝いたします。

また他のユーザーの方のお役に立つかもしれませんので、
OKだったデザイン定義を下記に。

コード: 全て選択

<xsl:for-each select="row"> 
<tr> 
<xsl:for-each select="entry"> 
<td></td> 
</xsl:for-each> 
<xsl:if test="position()=last()"> 
<xsl:if test="(count(//entry) mod 3) = 2"><td></td></xsl:if> 
<xsl:if test="(count(//entry) mod 3) = 1"><td></td><td></td></xsl:if></xsl:if> 
</tr> 
</xsl:for-each>

返信