- PR -

xsltで動的に値を表示させるには?

1
投稿者投稿内容
おざ
会議室デビュー日: 2006/05/10
投稿数: 2
投稿日時: 2006-05-10 14:33
初めて投稿いたします。
おざと申します。XSLT初級者です。
下記の様なコードで"type1"の方法で変数をうまく使って
<leaf>のテキスト値を取り出したいと考えています。
コード:
<?xml version="1.0"?>

<?xml-stylesheet	type="text/xsl"	href="test.xsl"?>
<root>
    <trunk>
        <branch>
	    <leaf>
	        worm
    	    </leaf>
        </branch >
    </trunk>
</root>



コード:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
    <xsl:template	match="/">
	<!--type1*******************************************************-->
	<xsl:value-of	select="cancat('root/trunk/branch/','leaf'"/>
	<br/>
	
         <!--type2*******************************************************-->

	<xsl:value-of	select="root/trunk/branch/leaf"/>
	</xsl:template>
</xsl:stylesheet>


が、実際には"root/trunk/branch/leaf"
と表示されてしまいます。

ところが"type2"の方法を取れば"worm"と望む値になります。
色々を手を尽くしてみたところどうやら"concat関数"により
xsl:value-ofのselect属性に文字列が渡っているのがよくない
ところまでは分かりました。

これは例示のコードなのでものすごく単純表示しており、わざわざ
文字列結合する必要はないのですが実際あつかうxmlファイルではいくつも要素があり
(つまり<leaf1>,<leaf2>...といくつも登場すると思ってください)
固定文字(パス)と変数化した要素名の文字列とで結合して値を割り出したいのです。

そこでお伺いしたいのは

  • concat関数を使った際の回避方法
  • concat関数を使わない場合のパスの連結方法

のいずれかなのですがこれと言う情報に辿りつけないでおります。
もし上記いずれどちからの方法でも結構ですので
ご存知の方がいらっしゃればご教授願えませんでしょうか。
よろしくお願いします。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2006-05-10 15:23
XPath式の文字列は2回評価しません。
cancat( の返値 をそのまま出力するだけ、
さらに XPathとして 評価(eval)しません。

コード:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ELEMENT xsl:stylesheet ANY>
<!ENTITY PA "root/trunk/branch/">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<br/>
<xsl:value-of select="&PA;leaf"/>
</xsl:template>
</xsl:stylesheet>


固定部なら、エンティティが使えます。
=====================
その前に、「カレントノード」「コンテキスト」の理解したほうがいいかも。
一般に文字列連結不要な書き方で済ませている、だから検索しても出ないのだ。

[ メッセージ編集済み 編集者: MMX 編集日時 2006-05-10 15:49 ]
ゆう
常連さん
会議室デビュー日: 2003/06/27
投稿数: 45
投稿日時: 2006-05-10 15:27
 変数に出力対象となるノード名称を指定しておき、出力部のxpath表現で
ノード名称name()と一致させるケースはどうでしょうか?

 複数の指定値(leaf1,leaf2など)がある場合は、variableをparamにして
テンプレート一致の際にノード名称を引数として与えれば対応できるかも。

コード:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:variable name="name">leaf</xsl:variable>

<xsl:template match="/">
<!--type1*******************************************************-->
<xsl:value-of select="root/trunk/branch/*[name() = $name]" />
</xsl:template>
</xsl:stylesheet>


(テスト環境:IE6)

[ メッセージ編集済み 編集者: 悠 編集日時 2006-05-10 15:39 ]
未記入
常連さん
会議室デビュー日: 2005/07/04
投稿数: 31
投稿日時: 2006-05-10 16:09
普通は悠さんのようにidなりnameなりの属性をつけてstringからノードを取得できるようなxml構造にすると思いますけど。

あえてこのままでやってみる。

XML
コード:
<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<root>
<leafs>
<leaf>leaf1</leaf>
<leaf>leaf2</leaf>
</leafs>
<trunk>
<branch>
<leaf1>
worm
</leaf1>
<leaf2>
xxxx
</leaf2>
</branch >
</trunk>
</root>



test.xsl
コード:
<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="/root/leafs/leaf">
<xsl:call-template name="select-node-name">
<xsl:with-param name="node-name" select="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>

<xsl:template name="select-node-name">
<xsl:param name="node-name"/>
<xsl:for-each select="/root/trunk/branch/*">
<xsl:if test="name(.)=normalize-space($node-name)">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>





[ メッセージ編集済み 編集者: 未記入 編集日時 2006-05-10 16:18 ]
おざ
会議室デビュー日: 2006/05/10
投稿数: 2
投稿日時: 2006-05-10 17:19
>ご返答いただきましたお三人様

早速のご返答誠にありがとうございました。
まだまだ私の知識の及ばない点ばかりでしたが大変助かりました。
試しに悠さんの方法でやってみたところ望む結果になりました。

今回もっと色々と学んでおく必要があることが分かりためになりました。
また何かありましたらよろしくお願いします。

1

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