プロが教えるわが家の防犯対策術!

お世話になります。
下記のサイトを参考に
http://webcache.googleusercontent.com/search?q=c …
http://webcache.googleusercontent.com/search?q=c …
http://webcache.googleusercontent.com/search?q=c …

javascriptからxsltに値を渡したいと考え、下記のように設定してみているのですが、思うようにxsltファイルで参照出来ず、途方に暮れております。

どなた様か解決法などご教授願えませんでしょうか。お願い致します。
※環境は、FireFox3.5を使っておりまして、現状、FireFoxのみで動作すれば良いと考えてます。

--test-1.html----
<html><head>
<meta content="text/html; charset=utf8" http-equiv="content-type">
<title>JS+xslt</title>
<script type="text/javascript">
function tramsformlists(xmlFile, xslFile, resultNodeID, Num){//chTag=inputのthis.value
//alert("resultNodeIDは" + resultNodeID + "です。");
var xml, xslt, newDoc;
var doc = document;
var impl = doc.implementation;
// XML ドキュメントの読み込み
var xml = impl.createDocument("", "", null);
xml.async = false;
xml.load(xmlFile);
// XSL ドキュメントの読み込み
var xslt = impl.createDocument("", "", null);
xslt.async = false;
xslt.load(xslFile);
// XSLT プロセッサを作成
var xsltp = new XSLTProcessor();
xsltp.importStylesheet(xslt);

// 下記2つのどちらかの方法で取得したいと思ってますが、xslt側で、どちらの方法でも参照できないです
xsltp.setParameter ('', "param.num", param.value);
xsltp.setParameter ('', "Num", Num);

// XSLT 実行(戻り値は文書断片ノード)
var df = xsltp.transformToFragment(xml, doc);

// 結果を付加
//var t3 = doc.getElementById("LorRorC");
//t4=t3.options[t3.selectedIndex].value;
//alert("resultNodeIDは" + t4 + "です。");

var t1 = doc.getElementById("Div"+resultNodeID);
t1.innerHTML = "";
t1.appendChild(doc.importNode(df, true));

var t2 = doc.forms["msg_form"].elements["Textarea" + resultNodeID];
t2.value = (new XMLSerializer).serializeToString(df);//DOM ノードを XML データに書き出す

}
</script>
</head><body>
<form name="msg_form">
<ul>
<li>
<input type="button" value="Menu" onclick="tramsformlists('test0.xml','test0.xsl','Test','10')"><br>
<select name="num">
<option value="10" selected="selected">10</option>
</select>

<div id="DivTest"></div>
<textarea cols="50" rows="10" id="TextareaTest">あああああああ</textarea>
</li>
</ul>
</form>
</body></html>
----

--test0.xml---
<?xml version="1.0" encoding="utf-8"?>
<root>
<nolink_logo>
</nolink_logo>
</root>
----

--test0.xsl---
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8"/>
<xsl:template match="root">
<xsl:apply-templates select="nolink_logo"/>
</xsl:template>

<xsl:template match="nolink_logo">
<xsl:call-template name="Test" />
</xsl:template>

<xsl:template name="Test">
<xsl:variable name="menu" select="document('test1.xml')/root"/>
<xsl:param name="param.num">0</xsl:param>
<xsl:param name="Num">0</xsl:param>
<div id="{$param.num} {$Num}">画像を表示
<xsl:for-each select="$menu">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="url[1]"/>
</xsl:attribute>
<xsl:attribute name="target">_blank</xsl:attribute>
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of select="img[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:for-each>
</div>
</xsl:template>

</xsl:stylesheet>
----

--test1.xml--
<?xml version="1.0" encoding="utf-8"?>
<root>
<img>http://domain/image2.gif</img>
<url>http://domain/test.html</url>
</root>
----

大変恐縮ですが、どなた様かご教授頂けませんでしょうか
宜しく願い致します。

A 回答 (4件)

XSLT 1.0 規定(邦訳)11.4 節より:


| トップレベルに置く xsl:param エレメントでは、スタイルシートに渡すパラメータを宣言する。XSLT では、パラメータをスタイルシートに渡すためのメカニズムを定義しない。

トップレベルでの宣言なしに外部パラメータを受け取れるプロセッサを、私は知りません(あるのかもしれませんが)。

それと念のため、<param name="p1" select="0"/> と <param name="p2">0</param> は全くの別物です。前者は数値の 0 ですが、後者は <dummy>0</dummy> のような結果ツリー断片であり、型変換においてノードセットと同じように扱われます。例えば、boolean($p1) は false ですが、boolean($p2) は true です。

参考URL:http://www.infoteria.com/jp/contents/xml-data/RE …
    • good
    • 0
この回答へのお礼

再度の詳しいご解説およびご教授を頂きましてありがとうございます。

xsl:paramについては、テンプレート内で、値を受け取る際の変数宣言としてのイメージでしか使っていなかった為、xsl:paramの本来の使い方を忘れていました。

トップレベル以下に、グローバル変数としての宣言が必要という事だったのですね。

後、ご解説内容の

><param name="p1" select="0"/> と <param name="p2">0</param> は全くの別物です。前者は数値の 0 ですが、後者は <dummy>0</dummy> のような結果ツリー断片であり、型変換においてノードセットと同じように扱われます。例えば、boolean($p1) は false ですが、boolean($p2) は true です。

についてですが、
xsl:param(xsl書式)の基本な記述方法として
・<xsl:param name="変数名"/>
・<xsl:param name="変数名" select="式"/>
・<xsl:param name="変数名" select="式"></xsl:param>
・<xsl:param name="変数名">処理されると変数値になる、テンプレートの内容</xsl:param>
例)<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="変数名1">
<shop>...</shop>
<area>...</area>
</xsl:param>

<xsl:param name="変数名2">
<shop>...</shop>
<area>...</area>
</xsl:param>
...

が、あげられると思いますが、javaやphp等のプログラム言語で判断される際のお話ですよね?

<xsl:call-template name="myStyle">
<xsl:with-param name="param1">silver</xsl:with-param>
<xsl:with-param name="param2">black</xsl:with-param>
</xsl:call-template>

<xsl:template name="myStyle">
<xsl:param name="param1">white</xsl:param>
<xsl:param name="param2">white</xsl:param>
ここで変数宣言しているparam1やparam2の値を上書きして使ってます。
</xsl:template>
※先の、「型変換においてノードセットと同じように扱われます。」とおっしゃるのは、話が違うように感じてしまいます。

下記で、
>@select 属性に、値が渡されなかったときのデフォルト値を書くこともできます。

と、教わり

><param name="p1" select="0"/> と <param name="p2">0</param> は全くの別物です。

と、お教え頂き、

xsl:param(xsl書式)の基本な記述方法としての先の例による記述で、現状問題なく使えている事から、少し気になりましたので・・・。

お手数ですが、もし、この点についての自分の誤解に関するご説明など、お教え頂けませんでしょうか。

お礼日時:2012/01/15 15:39

No.2 お礼の内容に関して。

XSLT 1.0 規定の 11.2 節にもありますが、

<xsl:param name="n" select="2"/>
<xsl:value-of select="child::HOGE[$n]">

上記は 2 番目の子 HOGE 要素の文字列値を出力するのに対し、

<xsl:param name="n">2</xsl:param>
<xsl:value-of select="child::HOGE[$n]">

こちらは 1 番目の子 HOGE 要素の文字列値を出力します。なぜでしょうか?

後者の $n は <dummy>2</dummy> のような断片だからです(DOM で言う DocumentFragment)。XPath 1.0 規定 2.4 節によれば、述語式 [...] の中身は、数値以外であればブール値変換されるとあります。後者の $n は数値ではないのでブール値変換されますが、このときの変換規則はノード集合の規則にしたがいます。すなわち、ノード集合が空でなければ true です。ゆえに、child::HOGE[$n] は child::HOGE[true()] となり、全ての子 HOGE 要素を返します。

さらに、value-of 要素の select 属性は、評価結果を string() 関数を適用したかのように文字列に変換します(XSLT 1.0: 7.6.1 節)。string() 関数にノード集合を渡した場合、文書出現順で最初のノードの文字列値を返します(XPath 1.0: 4.2)。

だから、上のような結果になるわけです。これは XSLT 1.0/XPath 1.0 の規則であり、Java や PHP のような外部プログラムとは全く関係ありません。XSLT は暗黙の型変換が異常なほど多く、誤りのもとになるので、可能ならばいちいち string()、number()、boolean() を書いて型変換を明示した方が良いくらいです。

XSLT 1.0 の結果ツリー断片は極めて使い勝手が悪く(XSLT 2.0 で少し改善されました)、多くの場合は XPath 1.0 の基本データ型(数値、文字列、ブール値、ノード集合)を渡したいのでしょうから、私は param 要素についても select 属性の方を勧めたわけです。
    • good
    • 0
この回答へのお礼

ご教授ありがとうございます。

xsltの型変換を考えてのアドバイスだったのですね。

暗黙的に型変換され、その際の変換規則の実例まで分かりやすくお教え頂いたこと、
また、URLのご掲示と詳細な節箇所までお教え頂き、とても参考になります。

今回は、色々とお教えいただき、本当にありがとうございました!

お礼日時:2012/01/17 21:33

なお、具体的なエラーメッセージが書かれていませんので見落としていましたが(すみません)、エラーの直接の原因は param 要素の位置です。

テンプレート内に置く param 要素は、あらゆる要素の先頭でなければなりません。とはいえ、外部パラメータを受け取る param 要素はテンプレートの外に置く、というのは前述の通りです。

ついでながら、結果 HTML 断片における id 属性が数値のみで構成されており、かつ空白が入っていること、あるいは元 HTML 文書に DOCTYPE 宣言がない(文法的に必須で、レンダリングやスクリプトエンジンを含むブラウザの振る舞いを切り替えます)など、HTML の文法にも不安点が散見されますので、念のためチェックして下さい。
    • good
    • 0

> xsltp.setParameter ('', "param.num", param.value);


> xsltp.setParameter ('', "Num", Num);

受け取り側 XSLT の記述がありません。トップレベルに以下が必要です。

<xsl:param name="param.num"/>
<xsl:param name="Num"/>

@select 属性に、値が渡されなかったときのデフォルト値を書くこともできます。コマンドラインなどからパラメータを受け取るときにも使いますので、覚えて下さい。値は原則として文字列として送られますが、一部のプロセッサでは数値などをそのまま渡すものもあります。
    • good
    • 0
この回答へのお礼

ご教授ありがとうございます。
既に、
<xsl:param name="param.num">0</xsl:param>
<xsl:param name="Num">0</xsl:param>
を記述し、何度もテスト行ってみたのですが、エラーとなってしまうようです。

トップレベルに以下が必要です。との事ですが、xsltにおいて、本来
<xsl:param name="・・・"/>
の指定はしなくとも特に問題ないはずと思いましたが・・・
もし正常な動作を確認可能なようでしたら、またご教授頂けますようお願いいたします。

お礼日時:2012/01/15 09:29

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!