xsl:for-each循环意外导致条件测试

时间:2016-03-02 16:03:08

标签: xml xslt recursion

考虑这个递归的XSLT模板:

<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>

以下XML输入文档:

use Doctrine\DBAL\Exception\UniqueConstraintViolationException;

// ...

try {
   // ...
   $em->flush();
}
catch (UniqueConstraintViolationException $e) {
    // ....
}

变量$ pSectionName的值为&#34; sEmicrania&#34;或&#34; sZona&#34 ;;这些是属性&#34; name&#34;的值。两个&#34;&lt; section&gt;&#34;元件。

当变量$ pSectionName的值为sEmicrania时,模板正确地将条件测试评估为true,但是如果变量的值为&#34; sZona&#34;测试评估为假。

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

1 个答案:

答案 0 :(得分: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>
相关问题