ページ 11

listitem内でのlist項目数をcountする方法

Posted: 2007年4月21日(土) 01:35
by love4
お世話になります。

実装したい内容は、list項目の総数をカウントしてmylistが1以上であれば1項目目の記事にエントリリンクをさせるという方法なのですが

http://cms.al-design.jp/phpbb/viewtopic ... hlight=eid
などを参考に考えて試行錯誤したのですが

1)リスト外でカウントさせて判断する(×)

コード: 全て選択

<xsl:if test="count(mylist/listitem)>1">
<a href="test.php{@href}">
</xsl:if>

<xsl:for-each select="mylist/listitem">
<xsl:if test="position()=1">
<xsl:value-of select="mytitle" />
</xsl:if>
</xsl:for-each>

<xsl:if test="count(mylist/listitem)>1">
</a>
</xsl:if>
これだと何も表示されなくなります。


2)リスト内でカウントさせて判断する(×)

コード: 全て選択

<xsl:for-each select="mylist/listitem">
<xsl:if test="position()=1">

<xsl:if test="count(mylist/listitem)>1">
<a href="test.php?eid={../../@id}">
<xsl:value-of select="mytitle" />
</a>
</xsl:if>

<xsl:if test="count(mylist/listitem)=1">
<xsl:value-of select="mytitle" />
</xsl:if>

</xsl:if>
</xsl:for-each>
これだとlist項目が2個以上のものは、表示されません。
count(mytitle)などにしても同じでした。


3)リスト外でカウントさせて1以上と1の処理を両方書く(○)

コード: 全て選択

<xsl:if test="count(mylist/listitem)>1">
<a href="test.php{@href}">
<xsl:for-each select="mylist/listitem">
<xsl:if test="position()=1">
<xsl:value-of select="mytitle" />
</xsl:if>
</xsl:for-each>
</a>
</xsl:if>

<xsl:if test="count(mylist/listitem)=1">
<xsl:for-each select="mylist/listitem">
<xsl:if test="position()=1">
<xsl:value-of select="mytitle" />
</xsl:if>
</xsl:for-each>
</xsl:if>
上のコードは単純に書きましたが、本当はifで分岐するコードが長くて複雑なため3)は避けたいと思っています。


4)リスト外で記事外にリンク要素を追記する(○)

コード: 全て選択

<xsl:for-each select="mylist/listitem">
<xsl:if test="position()=1">
<xsl:value-of select="mytitle" />
</xsl:if>
</xsl:for-each>

<xsl:if test="count(mylist/listitem)>1">
<a href="test.php{@href}">more</a>
</xsl:if>
上記の3か4のようにしないと出来ないものなのか、listitem内でのlist項目数をcountする方法はないのか、どなたかお教えいただけますでしょうか?

大きな勘違いやミスがあるかもしれませんが、宜しくお願いいたします。

Re: listitem内でのlist項目数をcountする方法

Posted: 2007年4月24日(火) 18:15
by webmaster
 love4さん、いつもお世話になっております。

 これは、普通にやろうとするとかなり困難な事例かと思います。
 いろいろ試していただき、恐縮です。

 根本的な問題は、for-eachを使って現在の処理対象がリスト項目の内部に
入ってしまっているのに、そこでリスト項目の数自体(つまり、自分自身の
親)を処理対象にする必要がある点が、いろいろ不都合を生んでいるものと
思います。

 基本的には(2)の方法が一番近いと思います。

コード: 全て選択

<xsl:for-each select="mylist/listitem">
 <xsl:value-of select="count(mylist/listitem)" />
</xsl:fo-each>
 このデザインの2行目は、実はcount(mylist/listitem/mylist/listitem)を計算
していることになってしまいます。これは、for-eachの中ではselectで指定した
要素がルートになる為です。

 試していないので間違っているかもしれませんが、ここでは次のように
書くとリスト項目の件数を取れるかと思います。

コード: 全て選択

<xsl:for-each select="mylist/listitem">
 <xsl:value-of select="count(../../listitem)" />
</xsl:fo-each>
 「count(..)」だけでもいけるような気もしますが、一度お試し下さい。

 また、XSLTでは「変数」という一時的なデータ保管場所を用意することが
できます。xsl:variableという命令を使います。

コード: 全て選択

<xsl:variable name="mylistcount" select="count(mylist/listitem)" />
<xsl:for-each select="mylist/listitem">
 <xsl:value-of select="$mylistcount" />
</xsl:fo-each>
 xsl:variableのname属性でデータに名前をつけ、selectでそのデータの
中身を指定します。
 そして、そのデータ名には、"$"+データ名、という形式で、デザイン定義中
のどこからでもアクセスすることができるようになります。

 以上、ざっとご説明させて頂きましたが、かなり分かり難いかと思いますので、
ご不明な点は再度ご質問頂ければ幸いです。