XSLT1.0对每个循环使用一个调用模板来填充表



因此,我最近开始在一个项目中使用XSL 1.0,需要迭代一个节点集,并为每个节点调用一个具有节点"属性"的模板
我说"属性"是因为我最终只做了一个内部标记,即我正在迭代的节点集看起来像这样:

<var>  
  <key>key 1 text here</key>  
  <value>value 1 text here</value>  
</var>  
  ....  
<var>  
  <key>key Nth text here</key>  
  <value>value Nth text here</value>  
</var>  

尽管我可以回到<var key="keytext" value="valtext" />之类的东西,如果有人认为这更好的话,我可以使用实际属性(事实上,这是我第一次处理这个问题的方式,但运气不佳)
无论如何,此节点集用于填充表单。用户从下拉菜单中选择项目名称,该下拉菜单将填充"计划名称"下拉菜单。一旦用户选择了计划名称,表单上就会有一个名为"构建变量"的表,该表将填充该计划的键/值配对。如果用户更改了计划名称,那么构建变量就会更改(我已经负责页面刷新和重新加载,并确保删除了旧变量),表中的行数可能会更改(每个键/值对一行)。

这是XSL的相关部分,它获取<var>标记的节点集并将其分配给$variables,然后使用<for-each>对它们进行迭代,获取键/值对并将它们传递给模板"widget_render"(我不提供widget_reder代码,因为它非常冗长(超过150行),并根据传递的参数调用其他模板)。在这种特殊的情况下,所有的widget_render本质上都是创建一个文本区域框,并用键或值的内容填充它-键的框不能由用户编辑,但它为值创建的框可以是

<xsl:variable name="variables" select="bamb-class:getPlanVariables($projVal, $planVal)" />    
<xsl:for-each select="$variables">  
   <xsl:variable name="key" select="./key" />  
   <xsl:variable name="value" select="./value"/>  
   <tr height="30">  
      <td class="datacell" colspan="1">  
         <xsl:call-template name="widget_render">  
            <xsl:with-param name="fieldName" select="concat('keyField[', position(), ']')"/>  
            <xsl:with-param name="renderCmd" select="'input'" />  
            <xsl:with-param name="default" select="$key" />  
            <xsl:with-param name="readOnly" select="'true'" />  
         </xsl:call-template>  
      </td>  
      <td class="datacell" colspan="1">  
         <xsl:call-template name="widget_render">  
            <xsl:with-param name="fieldName" select="concat('valueField[', position(), ']')"/>  
            <xsl:with-param name="renderCmd" select="'input'"/>  
            <xsl:with-param name="default" select="$value" />  
         </xsl:call-template>  
      </td>  
   </tr>  
</xsl:for-each>  

希望这是我正在做的事情的足够背景,所以这是有意义的。如果没有,请告诉我。

我的问题是:键和值似乎在对widget_render的调用模板中丢失了。这意味着在表中的任一<td>标记中都没有显示带文本的输入框。

然而,我可以在适当的<td>标签内执行<xsl:value-of select="$key" /><xsl:value-of select="$value" />,它会输出正确的值(信息就在那里,只是没有传递到widget_render或其他什么中)。由于没有value-of语句,我目前得到的只是正确的行数,但它们都是空的。

是的,我必须使用widget_render模板(不能只放在<input>标签或其他东西中),因为软件后来会重新使用表上的widget_reder逻辑来执行其他操作。不,这不是类型冲突,也不是我传球类型错误的事情,我已经确定了。

我不知道是我错过了什么真正愚蠢的东西,还是有什么更大的东西我只是不明白,但这件事让我很困惑。

简单地说:为什么调用模板(看起来)不起作用,并且在for each循环中用键/值对填充表?即使我知道for each在正确的节点集上迭代,并且$key$value在每次迭代中都有正确的赋值。

如有任何帮助,我们将不胜感激,谢谢!如果有什么不清楚的地方,或者有什么我无意中遗漏的信息需要知道,请告诉我。如果需要的话,我也可以抛出widget_render代码,但我怀疑这对任何人都没有帮助。

编辑:这里有一个链接到一个包含整个文件的dropbox:widget_render从第119行开始https://www.dropbox.com/s/zt3g9idprrca6ak/default-widgets.xml这是一个非常长的模板,它调用的所有其他模板也都在该文件中。

所以我设法找到了一个解决方案——对我来说有点像黑客,但它很有效,而且很适合我的需要。

我用这个替换了循环:

<xsl:variable name="planVariables" select="bamb-class:getPlanVariables($projVal, $planVal)"/>
<xsl:call-template name="renderAllRows">
    <xsl:with-param name="i" select="1"/>
    <xsl:with-param name="count" select="count($planVariables)"/>
    <xsl:with-param name="planVariables" select="$planVariables"/>
</xsl:call-template>

然后调用renderAllRows,该调用递归地调用自己以模拟xsl:for-each循环,直到表中的所有行都已渲染。

<xsl:template name="renderAllRows">
    <xsl:param name="i" />
    <xsl:param name="count" />
    <xsl:param name="planVariables" />
    <xsl:if test="$i &lt;= $count">
    <xsl:call-template name="renderRow" >
            <xsl:with-param name="rowNum" select="$i"/>
            <xsl:with-param name="planVariables" select="$planVariables"/>
        </xsl:call-template>
    </xsl:if>
<!-- recursion here -->
    <xsl:if test="$i &lt;= $count">
        <xsl:call-template name="renderAllRows">
            <xsl:with-param name="i" select="$i + 1"/>
            <xsl:with-param name="count" select="$count"/>
            <xsl:with-param name="planVariables" select="$planVariables"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>
<xsl:template name="renderRow">
    <xsl:param name="rowNum"/>
    <xsl:param name="planVariables"/>
    <xsl:variable name="key" select="exsl:node-set($planVariables)[position()=$rowNum]/key"/>
    <xsl:variable name="value" select="exsl:node-set($planVariables)[position()=$rowNum]/value"/>
    <tr height="30">
        <td class="datacell" colspan="1">
            <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="concat('keyField[', $rowNum, ']')"/>
                <xsl:with-param name="renderCmd" select="'input'" />
                <xsl:with-param name="default" select="$key" />
                <xsl:with-param name="readOnly" select="'true'" />
            </xsl:call-template>
        </td>
        <td class="datacell" colspan="1">
            <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="concat('valueField[', $rowNum, ']')"/>
                <xsl:with-param name="renderCmd" select="'input'"/> 
                <xsl:with-param name="default" select="$value" />
            </xsl:call-template>
        </td>
    </tr>                
</xsl:template>

为了让一切正常工作,对widget_render的调用正在查看正确的上下文,创建它们应该创建的文本框并填充它们。感谢Jirka的提示,帮助我解决了这个问题。

相关内容

  • 没有找到相关文章

最新更新