XSLT条件/变量范围

时间:2010-07-02 12:20:31

标签: xslt scope

<xsl:choose>
    <xsl:when test="long convoluted expression">
        <xsl:element name="Class">123</xsl:element>
        <a lot more xsl:elements>
    </xsl:when>
    <xsl:when test="next very long expression">
        <xml:element name="Class">124</xsl:element>
        <a lot more xsl:elements>
    </xsl:when>
    <tens of more similar xsl:when>
</xsl:choose>

有没有办法用条件简化上面的代码?对于给定对象的每个类值,随后有数十行具有额外属性。这些属性根据类的值形成集合。 0-99类有一组额外的标签,每秒100-199级,当这些额外的标签组之一发生变化时形成维护噩梦。

我正在考虑这样的解决方案:

<xsl:choose>
    <xsl:when test="long convoluted expression">
        <xml:element name="Class">123</xsl:element>
        <xsl:variable name="outputclass" select="123">
    </xml:when>
    <xsl:when test="next very long expression">
        <xml:element name="Class">124</xsl:element>
        <xsl:variable name="outputclass" select="124">
    </xsl:when>
</xsl:choose>
<xsl:choose>
    <xsl:when test="$outputclass > 99">
        <xml:elements for classes 100-199 here>
    </xsl:when>
<xsl:choose>

但当然这会失败,因为outputclass变量不在同一范围内。有什么方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:6)

这个问题的最佳解决方案是众所周知的

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
    <xsl:variable name="voutType">
      <xsl:choose>
        <xsl:when test="long convoluted expression">123</xsl:when>
        <xsl:when test="next very long expression">124</xsl:when>
        <!-- Etcetera ... -->
      </xsl:choose>
    </xsl:variable>

   <Class><xsl:value-of select="$voutType"</Class>
         <xsl:choose>
            <xsl:when test="not($voutType > 99)">
                <!-- elements for classes 0 - 99 here -->
            </xsl:when>
            <xsl:otherwise>
                <!-- elements for classes 100-199 here -->
            </xsl:otherwise>
         <xsl:choose>
 </xsl:template>
</xsl:stylesheet>

请注意

  1. 为了给变量($voutType)赋值, <xsl:choose>指令必须在里面 {{1} }

  2. 您只需要指定一次<xsl:variable>元素 - 在其他所有元素之外。

  3. 如果元素名称已知,则不必使用<Class>

答案 1 :(得分:1)

如果你想轻松指定一堆属性(不是标签又称元素!),那么听起来像属性集是你需要的,你可能不会需要变量:

http://www.w3.org/TR/xslt#attribute-sets

假设属性值本身不依赖于类的值;只有他们的存在。

如果元素真的是你的意思,尝试使用带有输入参数的命名模板。在样式表的顶层:

<xsl:template name="classdef">
  <xsl:param name="classid"/>
  <!-- Note: I put the class elem in here so I don't have to
        write individual class ids more than once -->
  <xsl:element name="Class"><xsl:value-of select="$classid"/></xsl:element>
  <xsl:choose>
    <xsl:when test="$classid > 99">
      ...
    </xsl:when>
  </xsl:choose>
</xsl:template>

并在您的其他模板中:

<xsl:call-template name="classdef">
  <xsl:with-param name="classid">124</xsl:with-param>
</xsl:call-template>

有关参数的更多信息,请参阅http://www.w3.org/TR/xslt#variables

答案 2 :(得分:0)

我只做了几次XSLT,但每次看起来都是一个巨大的维护噩梦。无论如何,我认为你可以设置一个变量来说明类是什么,然后调用一个函数作为xsl:template匹配类作为arg。您可以将该函数声明为xsl:template name,因为您不希望自动匹配它。在函数内部,您应该能够编写出这100个值的脚本。不确定这是否有帮助,但它以可能的方式组织代码。