如何在XSL中的几个条件下设置全局变量

时间:2013-12-20 13:10:44

标签: xml xslt edit param

我正在尝试转换一个看起来像这样的xml文档:

<CData>
    <Description>whatever</Description>
    <Property>
        <SetValue>123</SetValue>
        <Description>whatever</Description>
        <DefaultValue>321</DefaultValue>
    </Property>
      <Property>
        <SetValue>999</SetValue>
        <Description>whatever</Description>
        <DefaultValue>721</DefaultValue>
    </Property>
</CData>

每个CData标记都是一个表,属性标记表示一个表行。现在,如果单个Property标签具有Default和SetValue,并且它们不同,我需要检查每个CDate标签。这背后的原因是我只想要DefaultValue和SetValue不同的表。这是检查工作正常:

<xsl:for-each select="CData">
  <xsl:for-each select="Property">
    <xsl:if test="SetValue">
      <xsl:if test="SetValue/text()!=''">
        <xsl:if test="DefaultValue">
          <xsl:if test="SetValue!=DefaultValue">
          //SET a Value
          </xsl:if
        </xsl:if>
      <xsl:if test="not(DefaultValue)">
      //SET a VALUE
      </xsl:if>
    </xsl:if>
  </xsl:if>
</xsl:for-each>

在这个检查中,我需要一个变量,如果条件为真,将设置变量,在此for-each循环之后,我想用if-tag检查变量,如果设置了,我想打印一个表。我现在唯一的问题是我不知道如何在循环中设置一个变量,我可以像全局变量一样使用。

1 个答案:

答案 0 :(得分:2)

这不是XSLT的工作方式 - 所有变量都是词法范围的,一旦创建变量就不能改变变量的值。

您需要稍微考虑一下这个问题。而不是循环的“程序”视图,逐个测试条件并设置标志,你需要更多地以声明的方式思考 - 使用谓词来选择你感兴趣的节点:

<!-- this variable will contain only the Property elements that have a SetValue
     and a DefaultValue that are different -->
<xsl:variable name="interestingProperties"
     select="CData/Property[SetValue != DefaultValue]" />

然后根据是否选择了任何节点采取措施:

<xsl:if test="$interestingProperties">
  <table>
    <xsl:for-each select="$interestingProperties">
      <tr>...</tr>
    </xsl:for-each>
  </table>
</xsl:if>

如果您想允许拥有DefaultValue的Property元素,那么您可以稍微更改谓词:

<!-- this variable will contain only the Property elements that have a SetValue
     and do not also have a DefaultValue which matches it -->
<xsl:variable name="interestingProperties"
     select="CData/Property[SetValue][not(SetValue = DefaultValue)]" />

这里我使用的是not(X = Y)而不是X != Y,因为当您处理可能包含零个或多个成员的节点集时,语义会略有不同。基本上SetValue != DefaultValue说“有一对SetValue和一个DefaultValue元素使得它们的值不同”(特别是这意味着必须至少有一个用于测试成功),而not(SetValue = DefaultValue)表示“不存在匹配的SetValueDefaultValue对”(如果SetValueDefaultValue[SetValue]遗失了,所以我们还需要一个单独的{{1}}来确保它存在。)