人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

前回、
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
の質問を見ていただけますでしょうか。

再度、皆さんのお知恵を貸していただければうれしいです。

よろしくお願いします。

●質問者: kuroda
●カテゴリ:ウェブ制作
✍キーワード:HTML XML XSL タグ 完璧
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● lains_you
●80ポイント ベストアンサー
<?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) &gt; 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 &lt; $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 &lt; $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さん、たびたびのご教示ありがとうございます。

なるほど、発想の転換でいろいろな条件が作れるんですね。

本当に助かりました!

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ