4

我的 XSL 模板中有一个循环,它遍历每个“事件”并显示某些信息。每个事件都有一个与之关联的表单。

我想将一些事件信息存储在变量中,以便我可以将它与表单提交一起传递。

首先,我尝试给变量一个简单的名称(例如“event_id”):

<xsl:for-each select="event">
    <div class="event">
        <div class="event_id">Event ID: <xsl:value-of select="@id" /></div>
        <xsl:variable name="event_id"><xsl:value-of select="@id" /></xsl:variable>
    </div>
    <form action="submit_label" method="post">
        <input type="hidden" name="event_id" value="{$event_id}"></input>
    </form>
</xsl:for-each>

但是当页面进入表单时出现此错误:

无法编译样式表:文件:.../war/jstl:: 第 81 行:变量或参数“event_id”未定义。

Pastebin XSL 代码:http
: //pastebin.com/CUgqxptb Pastebin 错误消息:http://pastebin.com/EuW0aV71

我假设这是因为变量和表单位于 for 循环中,并且名称必须是唯一的。(对吗?!- 更新:这是不对的)。尽管令人困惑的是,这不会产生相同的错误:

<form>
    <xsl:variable name="foo">bar</xsl:variable>
    <input type="text" name="{$foo}" placeholder="{$foo}"></input>
</form>

所以,我现在正在尝试的是这个,目的是我可以使用计数器(i)在表单输入字段中引用事件变量:

<xsl:variable name="i" value="0"></xsl:variable> 
<xsl:for-each select="event">
    <div class="event_id">Event ID: <xsl:value-of select="@id" /></div>
    <xsl:variable name="event_{$i}"><xsl:value-of select="@id" /></xsl:variable>

    <form action="submit_label" method="post">
        <input type="hidden" name="event_id" value="{$event_i}"></input>
    </form>

    $i++
</xsl:for-each>

(我知道value="{$event_i}"没有任何意义,但希望你明白)

这给了我以下错误<xsl:variable name="event_{$i}">

其值必须是 QName 或空格分隔的 QName 列表的属性具有值“event_{$i}”。

我尝试使用<xsl:variable name=<fn:resolve-QName("event",$i) />>,但随后出现此错误:

与元素类型“名称”关联的属性需要打开引号。

但是,当然,添加引号 ( <xsl:variable name="<fn:resolve-QName('event',$i) />">) 会给我这个错误:

与元素类型“null”关联的属性“name”的值不能包含“<”字符。

那么,关于如何获取 event_id 信息以便将其与我的表单一起发送的任何建议?谢谢!!!

更新:
进步!感谢下面的@Lukas 评论(参考https://stackoverflow.com/a/9261566/1590763),我现在正试图在 for 循环之外声明变量。这工作正常,但我认为我需要为每个事件级变量执行 5 次不同的变量业务,这似乎很臃肿......示例:http: //pastebin.com/EuW0aV71

更新 #2:
不需要做 5 次可变业务。只需要移动一些 div 标签。感谢@TimC 与我交谈。代码的最终工作版本:

<xsl:for-each select="event">
    <xsl:variable name="event_id"><xsl:value-of select="@id" /></xsl:variable>        
    <div class="event">
        <div class="event_id">Event ID: <xsl:value-of select="@id" /></div>
    </div>
    <form action="submit_label" method="post">
        <input type="hidden" name="event_id" value="{$event_id}"></input>
    </form>
</xsl:for-each>

完整代码在这里: http: //pastebin.com/gP06gYEg

4

3 回答 3

3

如其他问题所述,变量在范围内是局部的,并且仅存在于定义它们的块中。您遇到的问题是在粘贴箱中显示的实际 XSLT 中,xsl:variable声明位于div元素内。您的示例应该看起来像这样:

<xsl:for-each select="event">
    <div class="event_info">
       <div class="event_id">Event ID: <xsl:value-of select="@id" /></div>
       <xsl:variable name="event_id"><xsl:value-of select="@id" /></xsl:variable>
    </div>
    <form action="submit_label" method="post">
       <input type="hidden" name="event_id" value="{$event_id}"></input>
    </form>
</xsl:for-each>

这意味着该变量仅在div元素内的范围内,因此当您稍后尝试访问它时,它不再存在。

在您的情况下,解决方案是将声明移动到稍后在范围内的位置,即div元素之外(它仍然是主xsl:for-each循环中任何嵌套元素的范围

在您的示例中,这应该有效。

<xsl:for-each select="event">
    <xsl:variable name="event_id"><xsl:value-of select="@id" /></xsl:variable>
    <div class="event_info">
       <div class="event_id">Event ID: <xsl:value-of select="@id" /></div>
    </div>
    <form action="submit_label" method="post">
       <input type="hidden" name="event_id" value="{$event_id}"></input>
    </form>
</xsl:for-each>
于 2013-10-26T13:22:47.227 回答
0

我不太清楚为什么你想i成为变量名的一部分。这个怎么样,而不是:

<input type="hidden" name="event{position()}" value="{$event_id}"></input>
<!-- you didn't really define this variable either:   ^^^^^^^^^        -->

另请参阅这个相关的 Stack Overflow 问题:Counter inside xsl:for-each loop

于 2013-10-25T19:49:34.897 回答
0

我还没有测试过这个,但我想你可能想要更像这样的东西:

<xsl:for-each select="event">
    <xsl:variable name="event_id"><xsl:value-of select="@id" /></xsl:variable>
    <div class="event_id">Event ID: <xsl:value-of select="$event_id" /></div>

    <form action="submit_label" method="post">
        <input type="hidden" name="event{position()}" value="{$event_id}"></input>
    </form>
</xsl:for-each>

$i在这种情况下真的没有必要。

要回答您的一些其他问题:

“我假设这是因为变量在 for 循环中,并且名称必须是唯一的。(对吗?!)”

不完全的。变量名必须是唯一的,但这不是这里的问题。问题是您不能使用模板来构建自己。就像在 C 中一样,这是不合法的:

int i = 0;
int abc[i] = 3;  // or whatever other made-up syntax...point is you can't do this.

您不能即时创建变量

我也尝试使用<xsl:variable name=<fn:resolve-QName("event",$i) />>...

这源于一个类似的问题。XSL 文档本身必须是一个有效的 XML 文档,这意味着,除其他外,您不能在标记中包含标记。

<this <is<not<legal>>>syntax</this>

很多模板语言,如 ASP、PHP、JSP 和 ColdFusion 都会让它飞起来。XSL 不会。

最后,需要指出的是,XSL中的变量不是可变的。 它可能是该语言中名称最差的标签。 <xsl:variable>定义一个常数。所以你的线

$i++

实际上并没有改变 的值$i。有关它的非常详细的讨论,请参阅此相关问题。

于 2013-10-25T20:13:08.883 回答