http://q.hatena.ne.jp/1162962189
でXMLに関し質問させていただいた者です。
いただいた回答は完璧だったのですが、設問の条件が少し変わりました。
下記のXMLのように、<text>タグの前に別のタグ(ここでは<name>)があるケースがあり、"position()=1"のような指定ができないケースがあります。
-------------------------
<?xml version="1.0" ?>
<document>
<title>
<id>a</id>
<text>あああ</text>
</title>
<title>
<id>b</id>
<text>いいい</text>
</title>
<title>
<id>c</id>
<name>たろう</name>
<text>ううう</text>
</title>
<title>
<id>d</id>
</title>
<title>
<id>e</id>
<text>えええ</text>
</title>
<title>
<id>f</id>
<name>はなこ</name>
<text>おおお</text>
</title>
</document>
-------------------------
このXMLから下記のようなidとtextを併記したHTMLを生成するXSLを作りたいと思います。
出力したいHTMLの形式と条件は前回とまったく同じです。
※文字数の制限で書ききれませんでした。
http://q.hatena.ne.jp/1162962189
の質問を見ていただけますでしょうか。
再度、皆さんのお知恵を貸していただければうれしいです。
よろしくお願いします。
<?xml version="1.0" encoding="Shift_JIS"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html" encoding="shift_jis" indent="yes"/> <!-- title要素変数 --> <xsl:variable name="titles" select="//title[count(./id) != 0 and count(./text) != 0]"/> <!-- ルート --> <xsl:template match="/document"> <html> <body> <table border="1"> <xsl:if test="count($titles) > 0"> <xsl:call-template name="list"> <xsl:with-param name="no">1</xsl:with-param> <xsl:with-param name="count" select="count($titles)"/> </xsl:call-template> </xsl:if> </table> </body> </html> </xsl:template> <!-- リスト --> <xsl:template name="list"> <xsl:param name="no"/> <xsl:param name="count"/> <xsl:variable name="title1" select="$titles[position() = $no]"/> <xsl:variable name="title2" select="$titles[position() = $no + 1]"/> <tr> <xsl:call-template name="item"> <xsl:with-param name="id" select="$title1/id"/> <xsl:with-param name="text" select="$title1/text"/> </xsl:call-template> <xsl:choose> <xsl:when test="$no < $count"> <xsl:call-template name="item"> <xsl:with-param name="id" select="$title2/id"/> <xsl:with-param name="text" select="$title2/text"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <td> </td> </xsl:otherwise> </xsl:choose> </tr> <xsl:if test="$no + 1 < $count"> <xsl:call-template name="list"> <xsl:with-param name="no" select="$no + 2"/> <xsl:with-param name="count" select="$count"/> </xsl:call-template> </xsl:if> </xsl:template> <!-- TD内容 --> <xsl:template name="item"> <xsl:param name="id"/> <xsl:param name="text"/> <td> <xsl:value-of select="$id"/> <xsl:text>:</xsl:text> <xsl:value-of select="$text"/> </td> </xsl:template> </xsl:stylesheet>
ほぼ前回からの流用です。
select="//title[count(./id) != 0 and count(./text) != 0]"でid要素とtext要素を子要素として持つtitle要素のみを抽出しています。
上記の条件ではidやtextの値が空であっても良いようにしてありますが、空値以外のものを検索する場合はselect="//title[./id != '' and ./text != '']"などに修正してください。
IE7で動作確認。
lains_youさん、たびたびのご教示ありがとうございます。
なるほど、発想の転換でいろいろな条件が作れるんですね。
本当に助かりました!