2016-03-02 79 views
-1

考虑这个递归XSLT模板:的xsl:for-each循环意外的结果在条件测试

<xsl:template name="SUBREPORT_FIELDS" > 
    <xsl:for-each select="current()/section/@name"> 
    <xsl:choose> 
     <xsl:when test="current()/section/@name = $pSectionName"> 
     <xsl:call-template name="FieldSezione"/> 
     <xsl:call-template name="FIELDS"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:call-template name="SUBREPORT_FIELDS"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:for-each> 
</xsl:template> 

而下面的XML输入文件:

<box name="box3"> 
    <section name="sEmicrania"> 
    <box name="box4"> 
     <treecombobox name="tc"/> 
     <textmemo name ="tm"/> 
    </box> 
    <box name="box4"> 
     <section name="sZona"> 
     <box name="box5"> 
      <label name="label1"/> 
      <textmemo name="tmZona"/> 
     </box> 
     </section> 
    </box> 
    </section> 
</box> 

变量$ pSectionName将作为其值“sEmicrania”或“sZona”;这些是两个“<节>”元素的属性“名称”的值。

当变量$ pSectionName的值为sEmicrania时,模板正确地将条件测试评估为true,但如果变量的值为“sZona”,则测试评估为false。

我希望测试在两种情况下均返回true。

+1

请发表** **重复性的例子 - 请参见:[MCVE] –

+0

我认为你需要改变'current()/ section/@ name = $ pSectionName'就是'section/@ name = $ pSectionName'。 'current()'与'.'不同,尽管在大多数地方它们的行为方式都是一样的 – Pawel

+0

“传递变量”是什么意思?您的模板未设置为接受参数。 – Matthew

回答

0

我想你的模板,因为它目前为不会输出任何东西,甚至在pSectionName的情况下被设置为“sEmicrania”

你可以通过这样开始:

<xsl:for-each select="current()/section/@name"> 

但如果你的当前节点是box元素,这将只会选择任何东西。如果是这种情况,那么在xsl:for-each构造中,上下文将是name属性。但后来你有你的测试...

<xsl:when test="current()/section/@name = $pSectionName"> 
在这种情况下

current()name属性,你定位在。这没有一个叫section的孩子,所以这个测试是错误的。

而是调用xsl:otherwise以递归调用模板。这不会更改上下文,因此您仍然位于name属性上。因此,此时xsl:for-each将不会选择任何内容,因此没有任何内容会被输出。

我不完全确定你想达到什么,但我不认为你一定需要递归模板。如果你只是想选择一个匹配名称的section元素,你可以做这样的事情

<xsl:template match="box"> 
    <xsl:apply-templates select=".//section[@name = $pSectionName]" /> 
</xsl:template> 

<xsl:template match="section"> 
    <!-- Do what you need to do here --> 
</xsl:template>