- PR -

テンプレートの存在チェック

1
投稿者投稿内容
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2001-10-23 20:49
スタイルシート内で、テンプレートの存在チェックを行うことは無理でしょうか?
実際にやりたいことは、

<table>
<tr>
<xsl:apply-templates />
</tr>
</table>

と記述しておいて、テンプレートを適用するたびに<td>と</td>で括りたいのです。
しかし、この記述だと不可能なので、

<table>
<tr>
<xsl:apply-templates mode="row"/>
</tr>
</table>

と、modeを指定しておいて、

<xsl:template match="*" mode="row">
<td>
<xsl:apply-template />
</td>
</xsl:templates>

と、記述した中間のテンプレートを用意することで<td></td>を付加しているのですが、
テンプレートを用意していないタグが出現した場合、HTMLに<td></td>と出力されて
しまいます。
これをなんとか回避したいのですが、よい方法はありませんでしょうか?
テンプレートの存在チェックが行えれば、なんとか回避できるのですが・・・。

上記以外の方法で、<td></td>を出力できる方法もあれば、教えて頂きたいです。

よろしくお願いします。
みのる
会議室デビュー日: 2001/09/10
投稿数: 7
投稿日時: 2001-10-23 21:46
テンプレートで処理する箇所を括りたいのでしたら、
そのテンプレート側で<td>をつけてはいかがでしょうか?

<xsl:template match="*" mode="row">
<xsl:apply-templates />
</xsl:template>

<xsl:template match="elemA">
<td>
<!-- ここにelemAの処理 -->
</td>
</xsl:template>

こうすれば、処理されない要素には<td>は付きません。

[ メッセージ編集済み 編集者: みのる 編集日時 2001-10-24 01:37 ]
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2001-10-24 09:35
説明が足りませんでした。
実際やりたいことは、「テンプレートが呼び出される位置によって括るタグを変えたい」のです。

要するに、Aという個所で呼ばれると<td>でくくり、Bという個所で呼ばれると括らないといった
風にしたいのです。
miki
大ベテラン
会議室デビュー日: 2001/09/21
投稿数: 174
お住まい・勤務地: 東京都八王子市
投稿日時: 2001-10-24 12:21
テンプレートが存在するかどうかの判断は難しそうですね。
テンプレートの実行結果のtreeをvariableに保持し、そのサイズが0ならテンプレートが存在しないという風にして書いたのが次のコードです。

<xsl:template match="*" mode="row">
<xsl:variable name="temp">
<xsl:element name="td">
<xsl:apply-templates select="."/>
</xsl:element>
</xsl:variable>
<xsl:if test="string-length($temp)!=0">
<xsl:copy-of select="$temp"/>
</xsl:if>
</xsl:template>

<xsl:template match="tag">
<xsl:value-of select="."/>
</xsl:template>

<!-- default template -->
<xsl:template match="*"/>
みのる
会議室デビュー日: 2001/09/10
投稿数: 7
投稿日時: 2001-10-24 13:59
> 実際やりたいことは、「テンプレートが呼び出される位置によって括るタグを変えたい」のです。

それなら、テンプレートにパラメータを渡して処理するというのは いかが?

以下は、「要素elemRの属性typeが1なら子要素elemAを処理して<tag1>で括る。
 そうでなければ、子要素elemAは処理するだけ。」
という例です。

コード:
<xsl:template match="elemR">
	<xsl:call-template name="ApplyElemA">
		<xsl:with-param name="type" select="@type" />
	<xsl:call-template>
</xsl:template>

<xsl:template name="ApplyElemA">
	<xsl:param name="type" />
	<xsl:choose>
		<xsl:when test="$type = 1">
			<tag1>
				<!-- elemAの処理 -->
			</tag1>
		</xsl:when>
		<xsl:otherwise>
			<!-- elemAの処理 -->
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>


んー、でもこれも なかむらさんの欲しいものじゃないかも。
一つ、具体的な例を教えてもらえませんか?
元のXMLと求める結果があるとわかりやすいと思うんですが。
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2001-10-24 14:26
for MIKIさん
ありがとうございます。
これだと不要なタグは除くことができました。
こういう方法もあるんですね。
勉強になりました。

ただ、なんかHTMLのインデントがずれてしまいますが、これは使用している
ツールのせいかもしれません。

for みのるさん

簡単な例を書きますね。

XML
-----------------------------------------
<page>
 <!-- 配置方向の指定 -->
 <orientation>vertical</orientation>
 <!-- 部品 -->
 <part>サンプル1</part>
 <part>サンプル2</part>
 <part>サンプル3</part>
 <part>サンプル4</part>
    ・
    ・
</page>
-----------------------------------------

これを<orientation>の値によって以下のように変えます。

HTML(verticalの場合)
-----------------------------------------
<html>
<body>
<table>
 <tr><td>
  サンプル1
 </td></tr>
 <tr><td>
  サンプル2
 </td></tr>
 <tr><td>
  サンプル3
 </td></tr>
 <tr><td>
  サンプル4
 </td></tr>
</table>
-----------------------------------------
HTML(vertical以外の場合)
-----------------------------------------
<html>
<body>
<table>
 <tr>
  <td>
   サンプル1
  </td>
  <td>
   サンプル2
  </td>
  <td>
   サンプル3
  </td>
  <td>
   サンプル4
  </td>
 </tr>
</table>
-----------------------------------------

スタイルシート側では、<page>配下にどの要素が記述されても表示できるように
しなくてはならないため、<xsl:apply-template />と記述する必要があります。

一番簡単なのは、みのるさんのように引数を渡して処理を分割すればよいのですが
テンプレートの数が多いほどスタイルシートの大きさは膨れあがってしまいます。
それか、

<xsl:template match="*" mode="row">
 <xsl:apply-template select="." />
</xsl:template>

などとまとめて記述せず、

<xsl:template match="part" mode="row">
 <xsl:apply-template select="." />
</xsl:template>

と1つ1つ定義していけばよいのですが、テンプレートを追加するたびに、合わせ
て定義しなければならないので、できればまとめてしまいたいのです。
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2001-10-30 13:40
解決しました!

<xsl:for-each select="*">
 <td>
  <xsl:apply-template select="." />
 </td>
</xsl:for-each>

とするとOKでした。
とはいうものの、この記述は、XSLの使用的に正しいのでしょうか?
  <xsl:apply-template select="." />
は同名のタグが複数存在しても、1回しか処理をしません。
<xsl:for-each>でひっかけたときの位置と同じタグしか処理をしないみたいですが。
1

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