如何在XSLT中访问JavaScript变量

5
我有以下代码。
<xsl:result-document href="output1/output3/index.html" format="html">
 <html>
 <head>
<SCRIPT LANGUAGE="JavaScript">
function getParams() 
{
var idx = document.URL.indexOf('?');
var params = new Array();
if (idx != -1) {
var pairs = document.URL.substring(idx+1, document.URL.length).split('&amp;');
for (var i=0; i&lt;pairs.length; i++) {
nameVal = pairs[i].split('=');
params[nameVal[0]] = nameVal[1];
   }
}
return params;
}
params = getParams();
</SCRIPT>

<SCRIPT LANGUAGE="JavaScript">
val = unescape(params["value"]);
document.write("value = " + val);
</SCRIPT>
</head>

<body>
 <xsl:choose>
    <xsl:when test="a:id=''">
    <xsl:value-of select="a:name"/>
    </xsl:when>
 </xsl:choose>
</body>
</html>
</xsl:result-document>

我想在xsl:when中访问JavaScript变量'val'。 我需要这个值来运行条件。 有任何想法 - 如何做到这一点?

转换是在什么时候/如何发生的? - Dave Newton
这是不可能的。试着解释一下你想要实现什么,我们看看是否有其他方法。 - penartur
我有JavaScript代码来获取URL中的值。我能够通过JS函数从URL中获取值并将其打印出来。现在我需要使用这个val = unescape(params["value"]);代替问号放在XSL <xsl:when test="a:id='???'">中。 - user1402867
3个回答

1

多种XSLT引擎允许在转换周期中执行javascript。但是,您只需将脚本作为输出标记的一部分包含即可(即普通JS)。

请参阅IBM的示例。他们有用于包含和执行JavaScript的特殊标签,这会因引擎而异。请注意,他们使用函数从JavaScript中返回值,如果直接变量访问不可能,请编写一个函数以返回该值。


我看到了这个链接,但是我无法将它应用到我的代码中。你能帮我写那个函数吗? - user1402867

1

Saxon-CE是一款在浏览器中运行的XSLT 2.0处理器。它被编译为JavaScript,并提供了高水平的JavaScript互操作性。JavaScript / DOM节点、数字、字符串、布尔值和数组(转换为XSLT 2.0序列)在JavaScript / XSLT接口之间相对无缝地工作。

对于您的特定情况,Saxon-CE有多种选项;您可以使用ixsl:call()直接调用现有或注入的JavaScript函数,也可以使用ixsl:get()检索变量的值。或者,您可以从XSLT 2.0中完成整个过程:

[已根据评论中提到的更正进行编辑]

XSLT Code

这是相同的代码,以文本形式而非图形形式包含 - 没有格式。
<xsl:transform
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:f="urn:local-function"
    xmlns:a="urn:source-xml"
    extension-element-prefixes="ixsl"
    version="2.0"
>
    <xsl:template match="/">
        <xsl:variable name="urlparams" select="ixsl:get(
            ixsl:get(ixsl:window(),'location'),
            'search')"
            as="xs:string"/>
        <xsl:variable name ="pairs" select="tokenize(substring($urlparams,2), '&amp;')"
            as="xs:string*"/>
        <xsl:variable name="value" select="f:getValue($pairs)"/>
        <p>value: <xsl:value-of select="$value"/></p>
        
        <xsl:choose>
            <xsl:when test="a:id eq $value">
                <xsl:value-of select="a:name"/>
            </xsl:when>
        </xsl:choose>
    
    </xsl:template>
    
    <xsl:function name="f:getValue" as="xs:string*">
        <xsl:param name="pairs" as="xs:string*"/>
        <xsl:sequence select="for $p in $pairs,
           $v in substring-before($p, '=')
        return
            if ($v eq 'value')
                then substring($p, string-length($v) + 2)
            else ()"/>
    </xsl:function>

</xsl:transform>

1
答案不完整,因为您没有提供示例输入,但我希望您可以根据这个粗略的示例调整代码。还有一个错误,因为string-length($v) + 1应该是string-length($v) + 2 - 最后,“location.search”在下一个版本之前不受支持 - 您需要在“location”上使用ixsl:get,然后再次在“search”上使用 - 这次使用location作为上下文对象。 - pgfearo
它给了我一个错误 - 找不到匹配的0参数函数名为{http://saxonica.com/ns/interactiveXSLT}window()。 - user1402867
2
你需要使用Saxon-CE - 错误提示表明正在使用另一个不支持此扩展函数的XSLT处理器。你是否在使用Saxon-CE? - pgfearo

0
你所问的是不可能的:JavaScript 是在页面渲染时由浏览器执行的,没有任何绕过它的方法,因为 JavaScript 正在解析页面 URL,只有浏览器才知道。
另一方面,XSLT 生成 HTML 页面 - 因此它在浏览器甚至看到要执行的 JavaScript 之前就被执行了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接