- PR -

xsl:for-eachの入れ子について

1
投稿者投稿内容
minth
会議室デビュー日: 2007/08/10
投稿数: 2
投稿日時: 2007-08-10 17:21
xmlの内容をxslにてxsl:for-eachを使いループさせて表示させようとしているのですが、
xsl:for-eachの中のxsl:for-eachが巧くループしてくれず困っております。

-------test.xml-------
<?xml version="1.0" encoding="euc-jp"?>
<?xml-stylesheet href="/test.xsl" type="text/xsl"?>
<rss version="2.0">
<channel>
<title>RSSです。</title>
<item>
<title>更新内容1です。</title>
<categorys>
<ct_link>http://test.com/1.html</ct_link>
<category>カテゴリ1</category>
<ct_link>http://test.com/2.html</ct_link>
<category>カテゴリ2</category>
</categorys>
</item>
<item>
<title>更新内容2です。</title>
<categorys>
<ct_link>http://test.com/2.html</ct_link>
<category>カテゴリ2</category>
<ct_link>http://test.com/3.html</ct_link>
<category>カテゴリ3</category>
</categorys>
</item>
</channel>
</rss>
-------test.xml-------

-------test.xsl-------
<?xml version="1.0" encoding="euc-jp"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="euc-jp" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp"/>
<title>TITLE</title>
</head>
<body>
<xsl:for-each select="rss/channel/item">
<ul>
<li><xsl:value-of select="title"/></li>
<li>カテゴリー</li>
<li>
<xsl:for-each select="categorys">
<a>
<xsl:attribute name="href"> <xsl:value-of select="ct_link" /> </xsl:attribute>
[<xsl:value-of select="category" />] </a>
</xsl:for-each>
</li>
</ul>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
-------test.xsl-------

上記のxml xslにて実験したところ

入れ子の<xsl:for-each select="categorys">にて
<categorys>内の1つめのデータのみ表示され、2つめのデータが表示できません。

初歩的な勘違いかもしれない気がするのでが、ハマッてしまって抜け出せません・・・
どなたか訂正・教授頂けると幸いです。

よろしくお願いいたします。
会議室デビュー日: 2007/08/09
投稿数: 4
投稿日時: 2007-08-11 07:39
とりあえず下記のtest.xslでうまくいくと思います。
元のxslでは、

<xsl:for-each select="rss/channel/item">
...
  <xsl:for-each select="categorys">
...処理1
  </xsl:for-each>
...
</xsl:for-each>
となっています。これは、itemの子要素である各categorysについて、処理1を行うという意味になりますので、
次のようなxmlなら期待通り動きます。
<item>
 <categorys>
  data01
 </categorys>
  ..
 <categorys>
  data99
 </categorys>
</item>

ご提示のtest.xmlでは、<item>の子として<categorys>がひとつだけあり、その子として<ct_link>と<category>の組が複数あるようになっています。したがって、「<ct_link>と<category>の組」について繰り返すというコードにする必要があります。

私が書いたxslでは、<ct_link>の次に対応する<category>が必ず現れることを前提として、<ct_link>に関して繰り返しを行いながら、following-sibling::categoryを使って対応する<category>を取得しています。

元のxmlの構造では、次のような書き方も可能になるので、それに対応しようとすると、xslをそれなりに書かなければなりません。
<categorys>
 <ct_link>http://test.com/1.html</ct_link>
 <ct_link>http://test.com/2.html</ct_link>
 <ct_link>http://test.com/3.html</ct_link>
 <category>カテゴリ1</category>
 <category>カテゴリ2</category>
 <category>カテゴリ3</category>
</categorys>

下記のようになっていれば、<ct_link>と<category>が対になることが見た目にもはっきりしますし、処理もAAAAについて繰り返せばいいのでわかりやすいように思います(質問内容からは外れていますが)。
<item>
<categorys>
 <AAAA>
  <ct_link>http://test.com/2.html</ct_link>
  <category>カテゴリ2</category>
 </AAAA>
 <AAAA>
  <ct_link>http://test.com/3.html</ct_link>
  <category>カテゴリ3</category>
 </AAAA>
</categorys>



-- test.xsl ---
<?xml version="1.0" encoding="euc-jp"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="euc-jp" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp"/>
<title>TITLE</title>
</head>
<body>
<xsl:for-each select="rss/channel/item">
<ul>
<li><xsl:value-of select="title"/></li>
<li>カテゴリー</li>
<li>
<xsl:for-each select="categorys/ct_link">
<a>
<xsl:attribute name="href"> <xsl:value-of select="." /> </xsl:attribute>
[<xsl:value-of select="following-sibling::category" />] </a>
</xsl:for-each>
</li>
</ul>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>


[ メッセージ編集済み 編集者: 未 編集日時 2007-08-11 07:42 ]
minth
会議室デビュー日: 2007/08/10
投稿数: 2
投稿日時: 2007-08-12 02:24
未さん返信ありがとうございます。

なるほど〜、たしかに
<categorys>
 <ct_link>http://test.com/1.html</ct_link>
 <ct_link>http://test.com/2.html</ct_link>
 <ct_link>http://test.com/3.html</ct_link>
 <category>カテゴリ1</category>
 <category>カテゴリ2</category>
 <category>カテゴリ3</category>
</categorys>
と同意の構造になっていました^^;

構造的に意図していない書き方になっていましたのでXMLの方を
<categorys>
 <AAAA>
  <ct_link>http://test.com/2.html</ct_link>
  <category>カテゴリ2</category>
 </AAAA>
 <AAAA>
  <ct_link>http://test.com/3.html</ct_link>
  <category>カテゴリ3</category>
 </AAAA>
</categorys>
の構造にすることでまとまりました。

どうも有難うございました〜^^
1

スキルアップ/キャリアアップ(JOB@IT)